perm filename X3.IDA[COM,LSP] blob
sn#871721 filedate 1989-04-02 generic text, type T, neo UTF8
∂07-Mar-89 0254 X3J13-mailer clarification
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 7 Mar 89 02:54:26 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
id AA06496; Tue, 7 Mar 89 02:52:25 PST
Message-Id: <8903071052.AA06496@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
for x3j13@sail.stanford.edu; id AA06496; Tue, 7 Mar 89 02:52:25 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 7 Mar 89 05:47
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: clarification
In Symbolics' vote, Moon mentioned that he wasn't willing to vote on the
sections on the letter ballot because he was afraid they would be cast
in concrete. I should have made it more clear that these sections can
be changed, via clean-up, after they have been voted on.
I am trying to get incremental closure on the standard, just as one would
stop gratuitous changes on software being developed in a large system
a few modules at a time. That never means that the modules originally
"fixed" will not be subject to change if the whole system doesn't work!
Please do not be afraid to spend time reviewing these sections now and
commenting if there are problems. Even if the volume of reading looks
large, imagine how large it will look in a few months when you have
over 1000 pages to review.
Please review and vote!!!
kc
∂07-Mar-89 1334 X3J13-mailer hotel for march meeting
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Mar 89 13:34:03 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA03677g; Tue, 7 Mar 89 13:27:16 PST
Received: by challenger id AA28084g; Tue, 7 Mar 89 13:22:41 PST
Date: Tue, 7 Mar 89 13:22:41 PST
From: Jan Zubkoff <jlz@lucid.com>
Message-Id: <8903072122.AA28084@challenger>
To: x3j13@sail.stanford.edu
Subject: hotel for march meeting
I have reserved rooms for X3J13 but it is up to you to make your personal
reservations.
---jan---
∂07-Mar-89 1403 X3J13-mailer Agenda DRAFT
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Mar 89 14:03:22 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA03717g; Tue, 7 Mar 89 13:56:36 PST
Received: by challenger id AA28137g; Tue, 7 Mar 89 13:52:01 PST
Date: Tue, 7 Mar 89 13:52:01 PST
From: Jan Zubkoff <jlz@lucid.com>
Message-Id: <8903072152.AA28137@challenger>
To: x3j13@sail.stanford.edu
Subject: Agenda DRAFT
X3J13 Committee Meeting Agenda DRAFT
March 28 - 30, 1989
Fairfax, VA
1 Call to Order, Tuesday, March 28, 9:00am
2 Opening Remarks and Introductions
- Opening Remarks, Bob Mathis (10 minutes)
- Introduction of attendees
- Future meetings, Jan Zubkoff (5 minutes)
3 Approval of Agenda
4 Approval of Minutes
5 Other Business
6 Cleanup Subcommittee Report, Larry Masinter
7 Coffee Break 10:30
8 Cleanup Subcommittee Report continuation
9 LUNCH 12:00
10 Cleanup Subcommittee Report continuation
11 Recess, 5:00pm
12 Call to Order, Wednesday, March 29, 9:00am
13 Character Subcommittee Report, Thom Linden (4 hours)
14 Coffee Break 10:30am
15 Character Subcommittee Report continuation
16 Lunch 12:00
17 Character Subcommittee Report continuation
18 Compiler Subcommittee Report, Sandra Loosemore (2 hours)
19 Break 3:00
20 Compiler Subcommittee Report continuation
21 Recess 5:00
22 Call to Order, Thursday, March 30, 9:00am
23 Editorial Subcommittee Report, Kathy Chapman (1.5 hours)
24 Coffee Break 10:30
25 Cleanup Subcommittee Report continuation
26 Lunch 12:00
27 Cleanup Subcommittee Report continuation
28 Break 3:00
29 Cleanup Subcommittee Report continuation
30 Adjournment 5:00pm
∂07-Mar-89 1429 X3J13-mailer registration list
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Mar 89 14:29:22 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA03769g; Tue, 7 Mar 89 14:22:28 PST
Received: by challenger id AA28211g; Tue, 7 Mar 89 14:17:54 PST
Date: Tue, 7 Mar 89 14:17:54 PST
From: Jan Zubkoff <jlz@lucid.com>
Message-Id: <8903072217.AA28211@challenger>
To: x3j13@sail.stanford.edu
Subject: registration list
X3J13 Attendee Information
03/07/89
Name Institute Paid L1 L2 L3
David Bartley TI -0- y y y
Paul Beiser HP -0- y y y
Mary Boelk Johnson Controls, Inc. -0- y y y
Kathy Chapman DEC -0- - - -
Jeff Dalton University of Ediburgh -0- y y y
Patrick Dussud Lucid, Inc. -0- y y y
Dick Gabriel Lucid, Inc. -0- y y y
David Gray TI 50.00 y y y
Masayuki Ida Aoyama Gakuin University -0- y y
Gregor Kiczales Xerox Corp. -0- y y y
Dieter Kolb Siemans -0- y y y
Tim Koschmann Xerox -0- y y y
Aaron Larson Honeywell S&RC -0- y y y
Kevin Layer Franz, Inc. 50.00 y y y
Thom Linden IBM 50.00 y y y
David Loeffler MCC 50.00 y y y
Sandra Loosemore University of Utah -0- y y y
Barry Margolin Thinking Machines 50.00 y y y
Larry Masinter Xerox Corp. -0- y y y
Robert Mathis CONTEL -0- y y y
David Moon Symbolics -0- y y y
Cris Perdue Sun Microsystems -0- y y y
Dan Pierson Encore Computer -0- y y y
Kent Pitman Symbolics -0- y y y
Guy Steele Thinking Machines -0- y y y
Paul Tucker IBM -0- y y y
Walter van Roggen DEC -0- y y y
JonL White Lucid, Inc. -0- y y y
Jan Zubkoff Lucid, Inc. -0- y y y
∂08-Mar-89 0523 X3J13-mailer Issue: PLUS-ABNORMAL
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 8 Mar 89 05:22:59 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
id AA27292; Wed, 8 Mar 89 05:21:03 PST
Message-Id: <8903081321.AA27292@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
for x3j13@sail.stanford.edu; id AA27292; Wed, 8 Mar 89 05:21:03 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 8 Mar 89 08:20
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Issue: PLUS-ABNORMAL
Sorry about that. Disregard that last issue. It should have been sent
to cl-cleanup.
∂08-Mar-89 0520 X3J13-mailer Issue: PLUS-ABNORMAL
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 8 Mar 89 05:20:36 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
id AA27193; Wed, 8 Mar 89 05:18:36 PST
Message-Id: <8903081318.AA27193@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
for x3j13@sail.stanford.edu; id AA27193; Wed, 8 Mar 89 05:18:36 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 8 Mar 89 08:18
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Issue: PLUS-ABNORMAL
Issue: PLUS-ABNORMAL
References: +, ++, +++ (p. 325)
Category: CLARIFICATION
Edit history: 1-MAR-89, Version 1 by Chapman
Problem Description:
The description of +, ++, and +++
does not mention the possibility of abnornal termination of
the evaluation of the variable {\tt +}.
Are the values associated with {\tt ++},
and {\tt +++} are updated?
Proposal (PLUS-ABNORMAL:UPDATE)
If the evaluation of the variable {\tt +} is aborted for some reason,
then the values associated with {\tt ++},
and {\tt +++} are updated.
Rationale:
This clarification is primarily to establish the contents of these
variables in all cases.
Current Practice:
VAX Lisp updates the values.
Adoption Cost:
?
Benefits:
Disambiguity.
Conversion Cost:
?
Aesthetics:
None.
Discussion:
∂08-Mar-89 1649 X3J13-mailer February 21 Ballot
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 8 Mar 89 16:49:01 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA05400g; Wed, 8 Mar 89 16:42:11 PST
Received: by challenger id AA00614g; Wed, 8 Mar 89 16:37:36 PST
Date: Wed, 8 Mar 89 16:37:36 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903090037.AA00614@challenger>
To: x3j13@sail.stanford.edu
Subject: February 21 Ballot
Here is Lucid's vote. There are two conditional acceptances. One is
because several of us are rewriting the error terminology yet again.
The other is section 6.1 where I want to look at the notation
introduced there once more. Also, there are some minor problems with
the rest of the section, (for example, fill pointers and pathnames
should be described somewhere else.) The sections on CLOS (1.8, 2.3,
2.4, 2.5) were put together by Kathy, Linda DeMichiel, and me, so I
think they're ok from the CLOS committee's point of view.
________________________________________________________________________
Issue or section name | Version | Y | I | A |
------------------------------------------------------------------------
CUT-OFF-DATES | 4 | Y | | |
------------------------------------------------------------------------
ERROR-TERMINOLOGY | 5 | | I | |
------------------------------------------------------------------------
FONTS | 2 | Y | | |
------------------------------------------------------------------------
TOC | 1 | Y | | |
------------------------------------------------------------------------
Section 1.8 | 5.8 | Y | | |
------------------------------------------------------------------------
Section 2.3 | 5.8 | Y | | |
------------------------------------------------------------------------
Section 2.4 | 5.8 | Y | | |
------------------------------------------------------------------------
Section 2.5 | 5.8 | Y | | |
------------------------------------------------------------------------
Section 6.1 | 5.8 | | I | |
------------------------------------------------------------------------
-rpg-
∂08-Mar-89 1741 X3J13-mailer Feb. 21 Letter Ballot: editorial issues
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Mar 89 17:41:03 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 553455; Wed 8-Mar-89 20:38:11 EST
Date: Wed, 8 Mar 89 20:37 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Feb. 21 Letter Ballot: editorial issues
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <19890306214441.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890309013751.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
I'd like to change the Symbolics vote, since you told me two things
that none of us here knew before: that there will be an opportunity
for cleaning up these sections even after they are voted in now, and
that the CLOS sections had already been carefully reviewed by Gabriel
and that Gregor had said he was satisfied with them. As a result,
we're changing our vote on sections 2.3, 2.4, and 2.5 from I to Y.
The other three I votes should remain. For ERROR-TERMINOLOGY because
it seems to be actively changing, for section 1.8 because the section
is sketchy, and for section 6.1 because we haven't really understood
it yet. Section 6.1 looks fundamental, do you think it's important
to get a vote on it as soon as possible? If so, we at Symbolics could
try to concentrate our efforts there.
I'd also like to clarify the meaning of this paragraph of our reply:
The five numbered sections: We approve these in principle, but aren't
ready to cast them in concrete. We haven't had time to review them with
the extreme care warranted for a language standard, and don't know who
else, if anyone, has reviewed them that thoroughly.
This was certainly not meant to give the impression that we were
refusing to review this stuff! The problem is simply that except for
Pitman, who is on the editorial committee, no one here had seen any of
this before two weeks ago. Also as it happens it is an extremely busy
time for us right now. Two weeks would not enough time for a really
careful review even in slack times, but at the time it was impossible.
I personally plan to try to review the entire standard carefully, as
well as to browbeat several other people at Symbolics into doing careful
review of either the entire standard or selected sections for their
areas of expertise. That will take a significant amount of time, of
course, probably several months.
∂09-Mar-89 1340 X3J13-mailer Issue: SUBSETTING-POSITION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:40:03 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554074; Thu 9-Mar-89 16:37:07 EST
Date: Thu, 9 Mar 89 16:36 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: SUBSETTING-POSITION
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902200927.AA06837@decwrl.dec.com>
Message-ID: <19890309213655.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
I support SUBSETTING-POSITION:NONE. I think that subsets are
a good idea, but I also think that the X3J13 process has no
chance at all of coming up with a subset that is useful to
anyone in the time available. Therefore I think the standard
should propose no subsets, but should not contain any statement
(unlike, I think, Ada) to the effect that subsets are forbidden
or a bad idea.
∂09-Mar-89 1345 X3J13-mailer Issue: EXTENTIONS-POSITION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:45:26 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554086; Thu 9-Mar-89 16:42:43 EST
Date: Thu, 9 Mar 89 16:42 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTENTIONS-POSITION
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902242224.AA13754@decwrl.dec.com>
Message-ID: <19890309214233.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
I favor EXTENSIONS-POSITION:DOCUMENTATION.
I oppose EXTENSIONS-POSITION:DISABLE because it mandates a
particular development environment feature, but Common Lisp
has avoided saying anything about development environments
since that is an area of extreme controversy.
Gabriel's position of standing mute would be okay with me.
∂09-Mar-89 1349 X3J13-mailer Issue: MACRO-AS-FUNCTION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:49:18 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554092; Thu 9-Mar-89 16:46:30 EST
Date: Thu, 9 Mar 89 16:46 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: MACRO-AS-FUNCTION
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242236.AA14651@decwrl.dec.com>
Message-ID: <19890309214619.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Why don't we just change PROG1 and PROG2 to functions, now that
we have clarified that functions evaluate their arguments in
left-to-right order?
∂09-Mar-89 1350 X3J13-mailer Issue: UNSOLICITED-MESSAGES (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:50:21 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554094; Thu 9-Mar-89 16:47:35 EST
Date: Thu, 9 Mar 89 16:47 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSOLICITED-MESSAGES (Version 2)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242237.AA14750@decwrl.dec.com>
Message-ID: <19890309214725.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
UNSOLICITED-MESSAGES:NOT-TO-SYSTEM-USER-STREAMS is okay.
∂09-Mar-89 1352 X3J13-mailer Issue: UNSPECIFIED-DATATYPES (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:52:35 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554096; Thu 9-Mar-89 16:49:52 EST
Date: Thu, 9 Mar 89 16:49 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSPECIFIED-DATATYPES (Version 2)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242237.AA14708@decwrl.dec.com>
Message-ID: <19890309214942.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
I oppose UNSPECIFIED-DATATYPES:NO-EXCEPT-AS-EXPLICITLY-ALLOWED
on the grounds that it is unnecessary and that the problem it's
attempting to address (making it possible to check conformance
by machine) is impossible to solve.
∂09-Mar-89 1357 X3J13-mailer Issue: EXTRA-SYNTAX (Version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:57:48 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554101; Thu 9-Mar-89 16:55:10 EST
Date: Thu, 9 Mar 89 16:54 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTRA-SYNTAX (Version 4)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902271015.AA14142@decwrl.dec.com>
Message-ID: <19890309215459.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
I oppose EXTRA-SYNTAX:NO. The rationale says
It would be very difficult for a program-analyzing-program to detect
such an extension. Non-portable programs could easily result.
I can't see what's hard about detecting use of additional syntax not
specified -- that seems to be the easiest to detect of any
nonconformance. To take the canonical example of extending IF to allow
more than three subforms, surely it is very easy for a
program-analyzing-program to detect an invocation of IF with more than
three subforms and complain that the program is non-conforming.
∂09-Mar-89 1406 X3J13-mailer Issue: EXTRA-OPTIONAL-KEYWORD-ARGUMENTS (Version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 14:06:06 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554109; Thu 9-Mar-89 17:03:09 EST
Date: Thu, 9 Mar 89 17:02 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTRA-OPTIONAL-KEYWORD-ARGUMENTS (Version 3)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902271016.AA14193@decwrl.dec.com>
Message-ID: <19890309220257.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
I oppose both proposals. The adoption cost is:
Implementors will be required to determine which parts of their
implementations are conforming and which parts aren't. Implementors
will have to provide a candidate list of exceptions to the editorial
committee.
The second sentence strikes me as a lot of extra work that will just
delay closure on the standard.
The stated benefits are:
It will be more possible to write portable programs. Also, future
standards will be less likely to make changes that are incompatible
with current implementations.
I don't believe in the first benefit. This issue does not affect the
ability to write portable programs in any significant way. It only
affects whether particular implementations are more or less useful as
development tools for checking conformance. I believe that development
tools for checking conformance are a valuable item for which market
demand exists, but are not within the purview of X3J13.
The second benefit is true. However there are a large number of other
ways that future standards could be incompatible with current
implementations, none of which have been ruled out. For example, any
implementation that makes symbols accessible to the USER package other
than symbols in the LISP package risks name conflicts with future
additions to the LISP package. It's simply a fact of life that any
extension might be incompatible with an eventual standard; pioneers can
never be sure that everyone will follow in their exact footsteps.
∂09-Mar-89 1433 X3J13-mailer Issue: EXTRA-SYNTAX (Version 4)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 9 Mar 89 14:33:19 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA06700g; Thu, 9 Mar 89 14:26:23 PST
Received: by challenger id AA02174g; Thu, 9 Mar 89 14:21:48 PST
Date: Thu, 9 Mar 89 14:21:48 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903092221.AA02174@challenger>
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Issue: EXTRA-SYNTAX (Version 4)
The rationale says:
``It would be very difficult for a program-analyzing-program to detect
such an extension. Non-portable programs could easily result.''
In fact the error terminology says this about extending the syntax
when it's allowed:
``Implementations are permitted to define unambiguous extensions to
the syntax of the construct being described. No conforming code can
depend on this extension. Implementations are required to document
each such extension. All conforming code is required to treat the
syntax as meaningless.''
Thus, the only syntactic extensions allowed would be those that
program analysis programs could detect.
There are some cases where we wish to disallow extensions and some
cases where we don't care. DEFCLASS is an example of one place we wish
to keep people away from. If there are vastly more places where we
don't care, that should be the default. I think it would take a
careful editorial process to decide whether it's easier to defaultly
allow or defaultly disallow. I think this issue is quite different
from that of extensions in general.
-rpg-
∂09-Mar-89 1539 X3J13-mailer Re: Issue: UNSPECIFIED-DATATYPES (Version 2)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Mar 89 15:39:49 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA04997; Thu, 9 Mar 89 16:37:40 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10028; Thu, 9 Mar 89 16:37:35 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903092337.AA10028@defun.utah.edu>
Date: Thu, 9 Mar 89 16:37:28 MST
Subject: Re: Issue: UNSPECIFIED-DATATYPES (Version 2)
To: chapman%aitg.dec@decwrl.dec.com
Cc: x3j13@sail.stanford.edu,
David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Thu, 9 Mar 89 16:49 EST
I agree with Moon. Leaving the behavior undefined gives an
implementation permission to do anything it wants, including starting
WWIII. "Anything" ought to include defining some useful behavior for
the situation, such as asking me if I really want to launch the
missiles.
-Sandra
-------
∂12-Mar-89 1616 X3J13-mailer Issue: UNSOLICITED-MESSAGES
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Mar 89 16:16:40 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 555408; Sun 12-Mar-89 19:14:06 EST
Date: Sun, 12 Mar 89 19:13 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242237.AA14750@decwrl.dec.com>
Message-ID: <890312191349.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
I agree that this is an important issue.
I am not sure I agree with the proposed solution -- partly because
I don't think it goes nearly far enough, and partly because I think the
wording for the place where it stops encourages might actually encourage
more `abuse' than currently exists.
I think it should be possible to know with certainly that calling EQ,
CONS, or even COMPILE, was not going to do I/O, at least in
the normal case. In exceptional cases, CONS might produce GC warnings
or COMPILE might produce compiler warnings, but never should COMPILE
type out anything like
Compiling FOO.
or should EQ type out
Performing EQ comparison of #<FOO 32> and #<BAR 17>.
Right now, nothing assures me of this and I find that disturbing.
This is the issue which I expected to `fix' this problem, and it does
not. In fact, its suggestion that it's ok to type such messages on
*TERMINAL-IO* may actually encourage what I consider to be an abominable
practice.
I would like it stated clearly that in the `normal situation' no
LISP function is permitted to do I/O unless the manual expressly
permits it.
Further, I think the current proposal permitting unsolicited messages
to go to *TERMINAL-IO* is a bad idea. I don't think unsolicited messages
should ever go directly to *TERMINAL-IO*. I am ammenable to them going to
documented streams which happen to have initial values that are synonym
streams to *TERMINAL-IO*, but
- I -don't- want them to be the standard CL streams, so I don't redirect
them by accident.
- I -do- want them to not be *terminal-io* so I can redirect them on
purpose.
Conceivably we could actually make a *JUNK-OUTPUT* which is initially a
synonym stream to *TERMINAL-IO*, but which is specially permitted to be
NIL to mean don't send the output anywhere, and we should say that all
unsolicited I/O has to go through there.
∂13-Mar-89 0714 X3J13-mailer cl-compiler mail
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 07:14:10 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA16287; Mon, 13 Mar 89 08:12:01 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02044; Mon, 13 Mar 89 08:11:59 -0700
Date: Mon, 13 Mar 89 08:11:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131511.AA02044@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: cl-compiler mail
I will be sending out the remaining batch of cl-compiler issues today.
I will also put FTP'able copies on host cs.utah.edu in directory
~ftp/pub/cl-compiler/pending. I'll send out a summary of issues when
I've gotten through them all.
It may be necessary for us to bring revised versions of some of these
proposals to the meeting. In particular, a few of them have been put
together at the last minute and haven't been reviewed thoroughly yet;
I've marked these as drafts so you'll be able to identify them. Any
comments or questions should be directed to cl-compiler@sail.stanford.edu.
-Sandra
∂13-Mar-89 0747 X3J13-mailer issue COMPILED-FUNCTION-REQUIREMENTS, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 07:47:01 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA17004; Mon, 13 Mar 89 08:44:52 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02070; Mon, 13 Mar 89 08:44:48 -0700
Date: Mon, 13 Mar 89 08:44:48 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131544.AA02070@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
Forum: Compiler
Issue: COMPILED-FUNCTION-REQUIREMENTS
References: CLtL p. 32, 76, 112, 143, 438-439
Issue FUNCTION-TYPE (passed)
Issue COMPILER-LET-CONFUSION
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue LOAD-TIME-EVAL (passed)
Issue COMPILE-ENVIRONMENT-CONSISTENCY
Category: CLARIFICATION
Edit History: V1, 3 Jan 1989 Sandra Loosemore
V2, 10 Jan 1989, Sandra Loosemore (additional proposal)
V3, 10 Feb 1989, Sandra Loosemore (new proposal)
V4, 11 Mar 1989, Sandra Loosemore (fix wording to agree
with other pending proposals)
Status: Ready for release
Problem Description:
There is confusion about what functions might be or must be of type
COMPILED-FUNCTION, and what attributes must be true of
COMPILED-FUNCTIONs. Is the distinction between COMPILED-FUNCTIONs and
other functions only one of representation, or can user programs infer
anything about COMPILED-FUNCTIONs? Are implementations required to
distinguish between compiled and non-compiled functions?
CLtL defines a COMPILED-FUNCTION as "a compiled code object". (Issue
FUNCTION-TYPE says only that COMPILED-FUNCTION must be a subtype of
FUNCTION.) Although it is not explicitly stated, CLtL implies that
compiled code must conform to certain rules; in particular, it states
that all macros are expanded at compile time, and specifies different
behavior for the COMPILER-LET and the EVAL-WHEN special forms
depending on whether they are interpreted or compiled.
The description of COMPILE in CLtL says that "a compiled-function object
[is] produced". It is not clear to everyone whether this implies that
COMPILED-FUNCTION-P must be true of such functions. CLtL says nothing
about whether functions defined in files compiled with COMPILE-FILE and
subsequently loaded must be of type COMPILED-FUNCTION.
The two proposals presented below present a simple model of the
compilation process. A minimal compiler could be implemented to
perform a code walk to apply the indicated transformations to the
function source code. Of course, most compilers will perform other
transformations as well, such as translating the Lisp source code into
a representation that is more compact or which can be executed more
efficiently.
Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN:
(1) Clarify that if a function is of type COMPILED-FUNCTION, the
following are guaranteed about the function:
- All macro calls appearing lexically within the function have
already been expanded and will not be expanded again when the
function is called. (See CLtL p. 143.) The process of
compilation effectively turns MACROLET and SYMBOL-MACROLET
constructs into PROGNs with all instances of the local macros
in the body fully expanded.
- The compiler must capture declarations to determine whether
variable bindings and references appearing lexically within
the function are to be treated as lexical or special.
- COMPILER-LETs nested lexically within the function will not bind
any variables when the function is called (CLtL p. 112). Again,
the process of compilation effectively turns COMPILER-LET
constructs into PROGNs with all macros in the body fully expanded.
- Lexically nested EVAL-WHENs have been processed as stated in
proposal EVAL-WHEN-NON-TOP-LEVEL; either the body is treated as
an implicit PROGN or as the constant NIL.
- If the function contains lexically nested LOAD-TIME-VALUE forms,
these have already been pre-evaluated and will not be evaluated
again when the function is called.
(2) Implementations are free to classify all functions as
COMPILED-FUNCTIONs, provided that all functions satisfy the criteria
listed in item (1). It is also permissible for functions that are
not COMPILED-FUNCTIONs to satisfy the above criteria.
(3) Clarify that COMPILE always produces an object of type
COMPILED-FUNCTION. Clarify when functions are defined in a
file which is compiled with COMPILE-FILE, and the compiled file is
subsequently LOADed, objects of type COMPILED-FUNCTION result.
Rationale:
This proposal allows users to count on COMPILE and COMPILE-FILE always
producing objects that are COMPILED-FUNCTION-P.
It assigns some specific properties to compiled functions. Users would
be able to rely on any function which is of type COMPILED-FUNCTION having
really been (at least partially) compiled.
It also states what many people believe to be the minimum functionality
required of a compiler.
Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN-COMPILE:
(1) Clarify that functions produced by COMPILE, or defined in a file
produced by COMPILE-FILE which has been subsequently LOADed, must
satisfy the same requirements listed in section (1) of proposal
TIGHTEN.
(2) Clarify that COMPILE always produces an object of type
COMPILED-FUNCTION. Clarify when functions are defined in a
file which is compiled with COMPILE-FILE, and the compiled file is
subsequently LOADed, objects of type COMPILED-FUNCTION result.
Rationale:
This proposal allows users to count on COMPILE and COMPILE-FILE always
producing objects that are COMPILED-FUNCTION-P.
It also states what many people believe to be the minimum functionality
required of a compiler.
However, it allows functions that have not been compiled also to be of
type COMPILED-FUNCTION. For implementations that do not use different
representations for interpreted and compiled functions, it would still
allow COMPILED-FUNCTION and FUNCTION to be synonymous, even if
interpreted functions do not satisfy the requirements for compilation.
Current Practice:
It appears that most implementations currently distinguish compiled
versus non-compiled functions on the basis of representation. It seems
unlikely that any implementation would have problems satisfying the
stated minimum requirements for compilation.
Lucid uses the same representation for both compiled and non-compiled
functions, except there is a bit in the header used to distinguish them.
A-Lisp uses the same representation for both compiled and interpreted
functions and currently labels them both as COMPILED-FUNCTION, but the
implementation of COMPILED-FUNCTION-P could be easily fixed to
distinguish "real" compiled functions.
On the TI Explorer, the COMPILE function can return an object of
either type COMPILED-FUNCTION or LEXICAL-CLOSURE, where the latter
consists of two components -- an environment and a COMPILED-FUNCTION.
There is confusion about whether microcoded functions should be
considered compiled or not.
Cost to implementors:
Unknown, but probably small for either proposal. Proposal
TIGHTEN-COMPILE is probably most consistent with current practice.
Cost to users:
Probably minimal. Since the COMPILED-FUNCTION type specifier is
currently ill-defined, it is hard to imagine that existing programs
can portably rely on any interpretation of what it means that is
inconsistent with what is presented here.
Benefits:
The specification of what the compiler must do is made more explicit.
Discussion:
The FIXNUM and BIGNUM types were also defined in CLtL solely on the
basis of distinguished representations, and that this definition has
proved inadequate for just about all portable usages of these type
specifiers. Defining COMPILED-FUNCTION solely on the basis of
distinguished representation seems like a bad idea.
David Gray notes:
We make good use of the type COMPILED-FUNCTION in our implementation,
but all of the accessor functions for objects of that type are
non-standard, which makes me wonder if it might be best to just remove
this type from the standard along with BIGNUM.
One use of the COMPILED-FUNCTION type is in declarations. A-Lisp and
Lucid, for example, can compile FUNCALL more efficiently if it can be
determined that the function is of type COMPILED-FUNCTION. However,
in order for such declarations to be really useful, there should be a
way to construct an object which is guaranteed to be of type
COMPILED-FUNCTION. Both of the proposals presented require COMPILE
and COMPILE-FILE to construct compiled functions.
Sandra Loosemore says:
I have a marginal preference for proposal TIGHTEN-COMPILE, since it
gives implementors more flexibility. To me it's more important that
COMPILE and COMPILE-FILE be guaranteed to do something, than that I
be able to test whether a function has had those things done to it.
∂13-Mar-89 0749 X3J13-mailer issue COMPILER-VERBOSITY, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 07:48:54 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA17056; Mon, 13 Mar 89 08:46:44 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02078; Mon, 13 Mar 89 08:46:42 -0700
Date: Mon, 13 Mar 89 08:46:42 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131546.AA02078@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILER-VERBOSITY, version 6
Forum: Compiler
Issue: COMPILER-VERBOSITY
References: CLtL p. 438-329; 426
issue COMPILER-DIAGNOSTICS
Category: ENHANCEMENT
Edit History: V1, 25 Oct 1988, Sandra Loosemore
V2, 12 Dec 1988, Dan L. Pierson (add USE-CONDITIONS)
V3, 15 Dec 1988, Dan L. Pierson (expand on conditions)
V4, 21 Dec 1988, Dan L. Pierson (reword and clarify)
V5, 06 Jan 1989, Sandra Loosemore (update discussion)
V6, 26 Jan 1989, Sandra Loosemore (remove USE-CONDITIONS)
Status: Ready for release
Problem Description:
Implementations vary widely in the amount of information that is printed
out by COMPILE-FILE. In some situations, it would be useful to control
how much information is printed.
Proposal COMPILER-VERBOSITY:LIKE-LOAD:
Introduce special variables, *COMPILE-VERBOSE* and *COMPILE-PRINT*,
with implementation-dependent initial values.
Add :VERBOSE and :PRINT keyword arguments to the function
COMPILE-FILE, analogous to those for the function LOAD.
The :VERBOSE argument (which defaults to the value of
*COMPILE-VERBOSE*), if true, permits COMPILE-FILE to print a message
in the form of a comment to *STANDARD-OUTPUT* indicating what file is
being compiled and other useful information.
The :PRINT argument (which defaults to the value of *COMPILE-PRINT*),
if true, causes information about top-level forms in the file being
compiled to be printed to *STANDARD-OUTPUT*. Exactly what is printed
will vary from implementation to implementation, but nevertheless some
information will be printed.
Introduce a special variable *LOAD-PRINT*, which has an initial value of
NIL. State that the default value of the :PRINT argument to LOAD is
*LOAD-PRINT* (rather than NIL).
Rationale:
This proposal makes COMPILE-FILE behave like LOAD. There is already
some precedent for doing this (for example, issue COMPILE-FILE-PACKAGE,
which makes COMPILE-FILE as well as LOAD rebind *PACKAGE*).
Adding the *LOAD-PRINT* variable allows the printing of messages by
LOAD to be controlled either on a global or a per-call basis.
Current Practice:
COMPILE-FILE prints out progress messages in nearly all
implementations.
Lucid provides a :MESSAGES keyword argument to COMPILE-FILE, which can
either be a stream to send messages to, or NIL to suppress messages.
The default value is T, which sends messages to "the standard terminal
device".
On the TI Explorer, COMPILE-FILE displays the name of the function
being compiled when the option :VERBOSE T is given or special variable
COMPILER:COMPILER-VERBOSE is true. (In other words, they use :VERBOSE
to mean what this proposal says to use :PRINT for.)
Symbolics Cloe already has a *LOAD-PRINT* variable.
Cost to implementors:
This is an incompatible change for some implementations. While the
changes required should be conceptually simple, their implementation
may involve a significant amount of grunt work. At least two
implementations already provide some similar mechanism for suppressing
messages.
Cost to users:
Some (non-portable) user code may break in implementations where this
is an incompatible change.
No user code should be broken by the addition of the *LOAD-PRINT*
variable, since the default behavior for the :PRINT keyword to LOAD
is unchanged.
Benefits:
Users are given a portable way to control how much information is printed
by COMPILE-FILE.
Discussion:
This issue addresses an extension to the language. If this proposal
is not accepted, the standard will simply continue not to say anything
about whether COMPILE-FILE can print progress messages, or what stream
such messages are directed to.
∂13-Mar-89 0748 X3J13-mailer issue COMPILER-DIAGNOSTICS, version 9
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 07:48:14 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA17028; Mon, 13 Mar 89 08:46:02 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02075; Mon, 13 Mar 89 08:45:59 -0700
Date: Mon, 13 Mar 89 08:45:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131545.AA02075@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILER-DIAGNOSTICS, version 9
Forum: Compiler
Issue: COMPILER-DIAGNOSTICS
References: CLtL p. 438-439, 62, 69, 160, 161
Condition System, Revision #18
S:>KMP>cl-conditions.text.34
Issue GC-MESSAGES
Issue RETURN-VALUES-UNSPECIFIED
Issue COMPILER-VERBOSITY
Category: CLARIFICATION, ENHANCEMENT
Edit History: V1, 15 Oct 1988, Sandra Loosemore
V2, 19 Oct 1988, Sandra Loosemore (minor fixes)
V3, 25 Oct 1988, Sandra Loosemore (input from Pitman & Gray)
V4, 01 Nov 1988, Sandra Loosemore (fix typos)
V5, 15 Dec 1988, Dan L. Pierson (new condition types)
V6, 15 Dec 1988, Sandra Loosemore (additions, fix wording)
V7, 16 Dec 1988, Dan L. Pierson (minor cleanup)
V8, 07 Jan 1989, Sandra Loosemore (expand discussion)
V9, 26 Jan 1989, Sandra Loosemore (simplify)
Status: Ready for release
Problem Description:
It is unclear whether various diagnostics issued by the compiler are
supposed to be true errors and warnings, or merely messages.
In some implementations, COMPILE-FILE handles even serious error
situations (such as syntax errors) by printing a message and then
trying to recover and continue compiling the rest of the file, rather
than by signalling an error. While this user interface style is just
as acceptable as invoking the debugger, it means that a normal return
from COMPILE-FILE does not necessarily imply that the file was
successfully compiled.
Many compilers issue warnings about programming style issues (such as
binding a variable that is never used but not declared IGNORE).
Sometimes these messages obscure warnings about more serious problems,
and there should be some way to differentiate between the two. For
example, it should be possible to suppress the style warnings.
Also, neither CLtL nor issue RETURN-VALUES-UNSPECIFIED states what the
return value from COMPILE-FILE should be.
Proposal COMPILER-DIAGNOSTICS:USE-HANDLER:
(1) Introduce a new condition type, STYLE-WARNING, which is a subtype
of WARNING.
(2) Clarify that ERROR and WARNING conditions may be signalled within
COMPILE or COMPILE-FILE, including arbitrary errors which may
occur due to compile-time processing of (EVAL-WHEN (COMPILE) ...)
forms or macro expansion.
Considering only those conditions signalled -by- the compiler (as
opposed to -within- the compiler),
(a) Conditions of type ERROR may be signalled by the compiler in
situations where the compilation cannot proceed without
intervention.
Examples:
file open errors
syntax errors
(b) Conditions of type WARNING may be signalled by the compiler in
situations where the standard explicitly states that a warning must,
should, or may be signalled; and where the compiler can determine
that a situation that "is an error" would result at runtime.
Examples:
violation of type declarations
SETQ'ing or rebinding a constant defined with DEFCONSTANT
calls to built-in Lisp functions with wrong number of arguments
or malformed keyword argument lists
referencing a variable declared IGNORE
unrecognized declaration specifiers
(c) The compiler is permitted to signal diagnostics about matters of
programming style as conditions of type STYLE-WARNING. Although
STYLE-WARNINGs -may- be signalled in these situations, no
implementation is -required- to do so. However, if an
implementation does choose to signal a condition, that condition
will be of type STYLE-WARNING and will be signalled by a call to
the function WARN.
Examples:
redefinition of function with different argument list
unreferenced local variables not declared IGNORE
declaration specifiers described in CLtL but ignored by
the compiler
(3) Require COMPILE and COMPILE-FILE to handle the ABORT restart by
aborting the smallest feasible part of the compilation. State that
both COMPILE and COMPILE-FILE are allowed to establish a default
condition handler. If such a condition handler is established,
however, it must first resignal the condition to give any
user-established handlers a chance to handle it. If all user error
handlers decline, the default handler may handle the condition in an
implementation-specific way; for example, it might turn errors into
warnings.
(4) Specify that COMPILE-FILE returns two values. The first value
is the truename of the output file, or NIL if the file could not be
created. The second value is T if the file was compiled without
errors, or NIL if errors were signalled during compilation.
Rationale:
Introducing the STYLE-WARNING condition allows handlers to distinguish
between potentially serious problems and mere kibitzing on the part of
the compiler.
Requiring any condition handlers established by the compiler to resignal
the condition before proceeding with any implementation-specific action
gives user error handlers a chance to override the compiler's default
behavior. For example, the user error handler could invoke a restart
such as ABORT or MUFFLE-WARNING.
Requiring the compiler to handle the ABORT restart reflects what
several implementations already do (although probably not using this
mechanism). The intent of the wording is to allow an implementation
to abort the entire compilation if it is not feasible to abort a
smaller part.
Requiring a second success-p value to be returned from COMPILE-FILE
gives the user some indication of whether there were serious problems
encountered in compiling the file.
Test Case/Example:
Here is an example of how COMPILE-FILE might set up its condition
handlers. It establishes an ABORT restart to abort the compilation
and a handler to take implementation-specific action on ERROR
conditions. Note that INTERNAL-COMPILE-FILE may set up additional
ABORT restarts.
(defvar *output-file-truename* nil)
(defun compile-file (input-file &key output-file)
(let ((*output-file-truename* nil)
(errors-detected nil))
(with-simple-restart (abort "Abort compilation.")
(handler-bind ((error #'(lambda (condition)
(setq errors-detected t)
(signal condition)
...)))
(internal-compile-file input-file output-file)))
(values *output-file-truename*
errors-detected)))
Current Practice:
No implementation behaves exactly as specified in this proposal.
In VaxLisp, COMPILE-FILE handles most compile-time errors without
invoking the debugger. (It gives up on that top-level form and moves on
to the next one.) Instead of signalling errors or warnings, it simply
prints them out as messages.
In Lucid Common Lisp, COMPILE-FILE invokes the debugger when it encounters
serious problems. COMPILE-FILE returns the pathname for the output file.
Symbolics Genera usually tries to keep compiling when it encounters errors;
so does Symbolics Cloe.
On the TI Explorer, the compiler tries to catch most errors and turn
them into warnings (except for errors on opening a file), but the user
can change special variable COMPILER:WARN-ON-ERRORS to NIL if he wants
to enter the debugger on an error signalled during reading, macro
expansion, or compile-time evaluation. The true name of the output
file is returned as the first value. A second value indicates whether
any errors or warnings were reported.
IIM Common Lisp's compiler handles errors using a resignalling mechanism
similar to what is described here.
Cost to implementors:
The cost to implementors is not trivial but not particularly high. This
proposal tries to allow implementations considerable freedom in what
kinds of conditions the compiler must detect and how they are handled,
while still allowing users some reasonably portable ways to deal with
compile-time errors.
Cost to users:
This is a compatible extension. This proposal may cause users to see
some small differences in the user interface to the compiler, but
implementations already vary quite widely in their approaches. Some
users will probably have to make some minor changes to their code.
Adding the STYLE-WARNING type may cause conflicts with programs
already using that name.
Benefits:
Users are given a way to detect and handle compilation errors, which
would simplify the implementation of portable code-maintenance
utilities. The behavior of the compiler in error situations is made
more uniform across implementations.
Discussion:
The issue of whether the compiler may print normal progress messages
is discussed in detail in a separate issue, COMPILER-VERBOSITY.
∂13-Mar-89 0815 X3J13-mailer issue CONSTANT-COMPILABLE-TYPES, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 08:15:04 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA17983; Mon, 13 Mar 89 09:12:55 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02083; Mon, 13 Mar 89 09:12:49 -0700
Date: Mon, 13 Mar 89 09:12:49 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131612.AA02083@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue CONSTANT-COMPILABLE-TYPES, version 8
Forum: Compiler
Issue: CONSTANT-COMPILABLE-TYPES
References: CLtL pp. 56, 77-80, 324
Issue CONSTANT-MODIFICATION
Issue CONSTANT-CIRCULAR-COMPILATION
Issue CONSTANT-ARRAY-ATTRIBUTES
Issue QUOTE-SEMANTICS
Issue LOAD-OBJECTS
Category: CLARIFICATION, ADDITION
Edit history: 11/07/88, V1 by Cris Perdue
11/14/88, V2 by Cris Perdue
11/22/88, V3 by Cris Perdue
12/20/88, V4 by Cris Perdue
01/06/89, V5 by Sandra Loosemore (minor editorial
clarifications, expand discussion)
03/05/89, V6 by Cris Perdue (more response to comments,
especially from Moon and and from Loosemore)
03/05/89, V7 by Loosemore (more editorial tweaks)
03/13/89, V8 by Loosemore (discussion)
Status: Ready for release
Problem description:
CLtL does not specify what objects can be in compiled constants and it
does not say what relationship there is to be between the
constant passed to the compiler and the one that is established by
compiling and then loading its file. Relevant remarks in CLtL
concerning file compilation and the definition of QUOTE suggest that
the compiler handles constants in ways that are not actually possible.
Introduction to the proposal:
The proposal CONSTANT-COMPILABLE-TYPES:SPECIFY attempts to spell out
what types can appear in compiled constants, and what it means when
they appear. Unless stated otherwise, in this proposal where the term
"constant" is used, it means a quoted or self-evaluating constant, not
a named (defconstant) constant.
The key is a definition of a form of equivalence between Lisp objects,
"similarity as constants". Code passed through the file compiler and
then loaded must behave as though quoted constants in it are "similar"
to quoted constants in the corresponding interpreted "source" code.
Because it is legitimate to compile in one address space and load into
a different one, it is necessary for the constraints to be defined
across address spaces. This proposal only concerns quoted constants
to be processed by COMPILE-FILE. Some other issues related to file
compilation are CONSTANT-COLLAPSING, CONSTANT-CIRCULAR-COMPILATION,
and QUOTE-SEMANTICS.
Some implementations "lose information" about some constants during
compilation. Typically all constant arrays become simple arrays
during the process of compiling and loading. We try to balance the
desire for more functionality against the effort required from
implementors.
Comments within the text of the proposal are enclosed in double angle
brackets, <<like this>>.
Proposal: CONSTANT-COMPILABLE-TYPES:SPECIFY
An object may be used as a quoted constant processed by COMPILE-FILE
if the compiler can guarantee that the resulting constant established
by loading the compiled file is "similar as a constant" to the
original. Treatment of uninterned symbols must be consistent across
the entire file as described below. There also is a constraint on
arrays which is not symmetrical; compilation can make arrays
"simpler", but not "less simple". (See below for the definition.)
We refer below to "quoted constants" or just "constants". In this
section these terms refer to objects appearing in expressions of the
form (QUOTE <object>), to objects used as self-evaluating forms, and
to objects appearing in code at locations described as "not
evaluated".
Some types such as streams are not supported in constants. Put
another way, an object containing one of these is not considered
similar as a constant to any other object. Some implementations may
support them and define how they are treated. For any object that
appears in a constant, but is not supported by the language as part of
a constant, the behavior of the compiler is unspecified; either the
the compiler and/or loader will handle that constant (in an
implementation-dependent manner) or the compiler will detect the
situation and signal an error.
Of the types supported in constants, some are treated as aggregate
objects. For these types, being similar as constants is defined
recursively. We say that an object of these types has certain
attributes, and to be similar as a constant to another object, the
values of the corresponding attributes of the two objects must also be
similar as constants.
This kind of definition has problems with any circular or "infinitely
recursive" object such as a list that is an element of itself. We
use the idea of depth-limited comparison, and say that two
objects are similar as constants if they are similar at all finite
levels. This idea is implicit in the definitions below, and applies
in all the places where attributes of two objects are required to be
similar as constants.
Here we define the notion of two objects being "similar as constants",
organizing the definition by type, and note additional constraints
that the compiler and loader working together must meet:
Number
If either of the two objects is a number, both must be of the same
type and must represent the same mathematical value.
Character
If either of the two objects is a character, both must be character
objects that represent the same character. <<Note that this
definition has to depend on the results of the Character Set
proposals.>>
Random-state
Let us say that two random-states are functionally equivalent if
applying RANDOM to them repeatedly always produces the same
pseudo-random numbers in the same order.
Two random-states are similar as constants exactly if copies of them
made via MAKE-RANDOM-STATE are functionally equivalent.
Note that a constant random-state object cannot be used as the "state"
argument to the function RANDOM (because RANDOM side-effects this
data structure).
Symbol
A symbol can only be similar to a symbol. References to interned
symbols are "by name". <<See issue COMPILE-FILE-SYMBOL-HANDLING for
details.>>
If a symbol is not interned, i.e. its home package is NIL, it is
treated in a rather special way. To be similar as a constant to
another symbol, both symbols must be uninterned and have the same
name.
Constants that contain uninterned symbols have to satisfy an extra
constraint. Consider the set of places in a constant that refer to
the same (EQ) uninterned symbol. In any similar constant, the
corresponding places must also all be EQ -- no more places and no
fewer. Moreover, COMPILE-FILE must arrange for the EQness of all
constant uninterned symbols that appear in the file to be preserved,
even if they are referenced in separate constants.
Because hash keys can be aggregate objects and because we treat hash
tables as unordered sets of <key, value> pairs, similarity of hash
tables is more complex. See under "Hash Tables", below, for the
definition.
Package
A package can only be similar as a constant to a package. References
to packages are permitted in any constant. References to packages are
"by name": two packages are similar as constants when their names are
similar as constants. Within a Lisp "address space", packages with
the same name are EQ.
At load time, the package becomes the same as returned by
FIND-PACKAGE, given the package name. An error is signalled if no
package of that name exists at load time.
AGGREGATE TYPES
---------------
For each of the types listed below, if either object is of the given
type, the two objects are similar as constants exactly if the other is
of that type and the values of all of the specified attributes are
similar as constants.
The attributes listed here can be called the "Basic Attributes" of
objects of each of these types.
Cons CAR, CDR.
Array For 1-dimensional arrays:
LENGTH, ARRAY-ELEMENT-TYPE, and ELT for all legal indices.
For arrays of other dimensions:
ARRAY-DIMENSIONS, ARRAY-ELEMENT-TYPE, AREF for all legal
indices.
An array of type SIMPLE-ARRAY can only be similar as a
constant to an array of type SIMPLE-ARRAY. However, we
allow the file-compiler a bit of latitude here. Where
constants in source code are displaced, have fill
pointers, or are adjustable, constants in the code
resulting from compilation and loading are permitted to
lack any or all of these qualities.
Hash Table Keys and value pairs. The table's test is unchanged
also. If the file compiler is given a constant containing a
a hash table that has keys that are similar as
constants, the consequences are undefined.
Consider a hash table as an unordered set of key and
value pairs. Two hash tables are similar as constants
exactly if there is a one-to-one correspondence between
the key and value pairs of each and a one-to-one
correspondence between the uninterned symbols of each
such that the two keys of each corresponding pair are
similar as constants and the two values are also similar
as constants. The correspondence of uninterned symbols
must be consistent with the correspondence defined for
the entire set of constants in the file.
Pathname Each pathname component.
OTHER TYPES
-----------
Stream, Compiled-Function, Readtable, Generic-function, Method
Objects of these types are not supported in compiled
constants.
Function Only function constants that are not compiled-functions
and do not close over any (lexical) variables are
supported in compiled constants.
Two such functions are similar as constants if their
SOURCE-LAMBDA-EXPRESSIONs are similar as constants.
Structure, Standard-object
<<There is a cl-cleanup issue, LOAD-OBJECTS, pending
which proposes a mechanism for dealing with objects.>>
For structure instances with no method defined at compile
time for MAKE-LOAD-FORM, the slot values and the name of
structure type (a symbol reference) are recorded by the
compiler and reconstructed by the loader.
Examples:
If source code contains a constant that could PRINT as (#1=#:FOO
#2=#:FOO #1# #2#), the constant resulting from compiling and loading
that code would have to be PRINTable as (#1=#:FOO #2=#:FOO #1# #2#).
If we make a hash table H, set three variables A, B, and C to
different uninterned symbols named FOO, and enter keys and values as
follows:
(setf (gethash a h) b)
(setf (gethash b h) a)
(setf (gethash c h) c)
If H appears in a compiled constant, after compiling and loading it,
(let ((value (list)))
(maphash #'(lambda (x y) (push (list x y) value)) h)
value)
could print as
((#1=#:FOO #2=#:FOO) (#2# #1#) (#3=#:FOO #3#))
but not as
((#1=#:FOO #2=#:FOO) (#2# #3=#:FOO) (#3# #1#))
Rationale:
For the benefit of users, this proposal tries to define a fairly large
set of types that all Common Lisp implementations are to handle. It
also attempts to leave room for implementations to differ. Some
implementations have made opposing choices because the language
doesn't specify one over the other. Some implementations already
handle constants that this proposal defines as not legal in Common
Lisp programs, and that is useful to users of those systems.
Different implementors have different amounts of resources to apply to
their system, and implementations differ in their whole approach in
some cases.
This proposal appears to reflect user demand and appears not to exceed
the capabilities of most implementations of the language.
The proposal ensures that all references to the same uninterned symbol
within a file will all map to references to just one uninterned symbol
after compiling and loading. This is needed to support PCL.
Current practice:
>From Gail Zacharias (Nov 14): "Coral pretty much implements this
proposal (I think we currently coalesce hash table keys, but that's
just a bug that will be fixed). We also fasdump packages (using the
package name) and compiled functions (but not foreign functions). For
symbols, we dump the name, and if (roughly speaking) the symbol would
get printed with a package prefix, we also dump the package name and
load the symbol into that package (otherwise it gets loaded into the
current load-time package)."
>From David Gray (Nov 9): "The Explorer can compile constant functions,
read tables, and hash tables; an error is signalled for a stream. A
package object used to break the compiler but in release 5 it has been
fixed to generate instructions to call FIND-PACKAGE on the package
name at load time." (Nov 15): [The Explorer does not guarantee
retention of displaced-to and displaced-index-offset attributes.]
"The Explorer also does not currently support dumping closures (either
compiled or evaluated), although non-closure compiled functions can be
dumped."
>From David Moon (Jan 24): "Symbolics Genera current practice: aside
from some current bugs we have with circular structures of certain
types and with preserving the identity of CONSes under EQ, this is
more or less consistent with our current practice, if you made the
changes implied by my earlier comments. We preserve the :displaced-to
and :fill-pointer array attributes. I doubt that we do what the
proposal says for hash-tables, readtables, and random-states. We
support dumping compiled and interpreted functions, but not closures,
which in effect means we don't support dumping functions."
>From Sandra Loosemore (Mar 3): "UCL currently can handle only
constants that are of type number, character, symbol, cons,
simple-vector, or string (which it turns into simple-string). It
signals an error if an attempt is made to compile any other kind of
object as a constant."
Adoption cost:
Not known. Probably moderate or low -- for most implementations. The
cost would be to implementors rather than users since this part of the
language is currently underspecified. The author believes the cost
will be reasonable for KCL, an implementation where there is some
concern about this issue.
This proposal is close to compatible with the Franz, Lucid, Coral,
Texas Instruments, and Symbolics implementations. It is probably
compatible or nearly compatible with other "Lisp Machine"
implementations.
Benefits:
Users would be able to use aggregate objects in constants with
confidence about the behavior of their code.
Conversion cost:
Where this proposal *requires* different behavior than an existing
implementation, there is a conversion cost for users of that
implementation. It appears that this cost will be small, less than
the cost of leaving things unspecified.
Esthetics:
Since there is no adequate definition at present, a fuller definition
would be more esthetic.
Discussion:
This proposal does leave some user-visible attributes of objects
unspecified across the compile-and-load process, except that they must
be consistent with the attributes that must be retained. This
situation is a compromise between the desire for full specification on
the one hand, and on the other hand the desire to leave freedom for
different implementations to remain different and to support some
optimizations such as compacting hash tables and "simplifying" arrays.
Proposals will be entertained for tighter specification of datatypes
such as arrays.
The full extension of the concept of coalescing of constants is to say
that they can be coalesced exactly when they are similar as constants.
Comparing functions semantically is intertwined with the specification
of what conforming programs and implementations are allowed to do.
This proposal does not attempt to do that since compiled functions are
not supported by this proposal in compiled constants.
The definition of similarity for random-states supports the
possibility of random states that are immutable because of being in
compiled constants.
Readtables need not be supported by an implementation. If a readtable
contains only symbols to represent functions, here is Cris Perdue's
suggested spec for similarity of readtables:
Character syntax type for each character in the table;
function for each readmacro character, mappings for
dispatch macros; whether terminating or nonterminating
for each readmacro.
Interest has been expressed by a number of people including users, in
support for user-definable "dumping" of CLOS objects and structure
instances. The cleanup issue LOAD-OBJECTS deals with this.
This subsumes the issue CONSTANT-ARRAY-ATTRIBUTES.
The main point of disagreement on this proposal over its handling
of constant functions.
Sandra Loosemore says:
I plan to submit an amendment to this proposal which would remove the
requirement that the compiler be able to dump non-compiled, non-closed
functions. The reason for removing this requirement is that there is
no way to portably construct an object which is guaranteed to be a
non-compiled, non-closed function. Note that implementations are
permitted to make all functions COMPILED-FUNCTIONs.
Dick Gabriel says:
I guess I pretty strongly object to leaving functions out of the list
of constants that can appear in compiled code. The part that's
disturbing is that such non-Lispy things like arrays, hashtables, and
pathnames get better treatment than functions, the most Lispy part of
Common Lisp. I wonder how many implementations will be forced to come
within an inch of the required functionality to implement a first-rate
CLOS?
The specification of the subset of functions that are acceptable as
compiled constants cannot be tested for within Common Lisp itself.
I suggest we ask implementors (Lucid included) to bite the bullet and
handle this case correctly. Won't our grandchildren appreciate us
treating Common Lisp like Lisp and not like PASCAL?
If we were to specify that all functions could appear as constants, we
would also need to clarify whether the closed-over variable bindings
become immutable, and also deal with whether bindings that are closed
over more than one function retain their uniqueness. Also, the cost
to implementors to add support for dumping non-interpreted functions
may be quite high.
∂13-Mar-89 0821 X3J13-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 08:21:42 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA18436; Mon, 13 Mar 89 09:19:31 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02090; Mon, 13 Mar 89 09:19:28 -0700
Date: Mon, 13 Mar 89 09:19:28 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131619.AA02090@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 7
Forum: Compiler
Issue: CONSTANT-CIRCULAR-COMPILATION
References: Issue CONSTANT-COLLAPSING
Issue QUOTE-SEMANTICS
Category: CLARIFICATION, ADDITION
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 14 Nov 1988, Cris Perdue
V3, 12 Dec 1988, Sandra Loosemore (merge versions 1 and 2)
V4, 03 Jan 1989, Sandra Loosemore (add PRESERVE-SHARING-ONLY)
V5, 06 Jan 1989, Sandra Loosemore (minor wording changes)
V6, 08 Feb 1989, Sandra Loosemore (replace FLAG with YES)
V7, 11 Mar 1989, Sandra Loosemore (error terminology)
Status: Ready for release
Problem Description:
CLtL does not specify whether constants containing circular or
recursive references may be compiled. It is also not clear whether
the compiler must preserve sharing of EQ substructures; that is, whether
subobjects that are EQ in the source code must remain EQ after being
compiled.
The proposals below apply to constants appearing in a file compiled by
COMPILE-FILE. If proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE
passes, then the same constraints would apply to all constants. The
minimal scope over which sharing would be required to be detected is
over a single call to EVAL or COMPILE.
In the proposals that follow, "preserving EQness" means that
subobjects that are EQ in the source code must remain EQ after being
compiled; that is, things don't get "less EQ" after compilation.
(Note that coalescing of constants implies that things may get "more
EQ".)
Proposal CONSTANT-CIRCULAR-COMPILATION:NO
State that the consequences are undefined if an object containing a
circular reference appears as a constant to be compiled. State that
the compiler is not required to preserve EQness of substructures.
Rationale:
This proposal would not require any existing implementation to change.
Disallowing portable programs from containing circular constants
allows compiled file loaders to use somewhat simpler implementation
strategies (for example, to build constants in a strict bottom-up
fashion).
Proposal CONSTANT-CIRCULAR-COMPILATION:PRESERVE-SHARING-ONLY
State that the consequences are undefined if an object containing a
circular reference appears as a constant to be compiled. State that
the compiler is required to preserve EQness of substructures within a
file compiled with COMPILE-FILE.
Rationale:
Disallowing portable programs from containing circular constants
allows compiled file loaders to use somewhat simpler implementation
strategies (for example, to build constants in a strict bottom-up
fashion).
Some programs (such as PCL) have come to depend on COMPILE-FILE
preserving the EQness of uninterned symbols, and it is cleaner
to require sharing to be preserved in general instead of making
symbols be a special case. Requiring sharing to be preserved still
allows loaders to build constants bottom-up.
Proposal CONSTANT-CIRCULAR-COMPILATION:YES
State that objects containing circular references may legitimately
appear as constants to be compiled. State that the compiler is
required to preserve EQness of substructures within a file compiled
with COMPILE-FILE.
Rationale:
Users seem to expect this functionality, and some implementations
already provide it.
Current Practice:
A-Lisp preserves EQness of substructures (since it makes an effort to
collapse isomorphic structures) but signals an error if an attempt is
made to compile a circular constant. PSL and Utah Common Lisp both
get stuck in an infinite loop if an attempt is made to compile a
reentrant structure. The TI Explorer compiler is able to reproduce
recursive lists and arrays, but currently hangs in a loop on a
circular list. Neither the Explorer nor Symbolics Genera 7.x detects
EQness of list CDRs. Lucid handles circular constants correctly.
Franz uses a flag to control whether or not to attempt to detect
circular constants. KCL handles circular structures, but only detects
sharing of top-level structure (it does not traverse constants to look
for shared substructure).
Cost to implementors:
We know of no implementation that would have to change under proposal
NO.
For proposal YES, some implementations would require sweeping
changes; in some cases a completely different dumper/loader strategy
would have to be implemented.
The cost of proposal PRESERVE-SHARING-ONLY would fall somewhere in
between.
Cost to users:
The situation now is that programs which depend upon circularity or
sharing of substructure being preserved by the compiler are already
nonportable. Proposal NO simply formalizes the status quo. Proposal
YES would offer users functionality that is currently not portable.
Benefits:
An area of ambiguity in the language is removed.
Discussion:
The issue of compiler speed is largely a red herring on this issue;
the overhead of detecting circularities is generally quite small. The
main question is whether we should require some implementations to
completely redo their compiler/loader interface in order to support
circular constants.
It has been argued that any "serious" implementation will support
circular constants anyway, because of customer demand. However, since
there appears to be only one implementation (Lucid) that now
implements proposal YES in its full generality, perhaps the demand for
this feature is not really all that strong.
Earlier drafts of this writeup contained a proposal FLAG which would
have added a variable *COMPILE-CIRCLE*, similar to *PRINT-CIRCLE*.
However, there were unresolved problems about what would happen if the
value of this variable were altered within the file being compiled,
and it was generally agreed that this proposal didn't have any
particular advantages over proposal YES and just introduced
unnecessary hairiness.
Since it is usually fairly simple to detect circular constants,
Loosemore would support an amendment to proposals NO and
PRESERVE-SHARING-ONLY to change the first sentence to read:
State that the consequences are unspecified if an object containing
a circular reference appears as a constant to be compiled.
Implementations must either correctly handle the circular reference
or signal an error.
This is similar to the language which is already used in proposal
CONSTANT-COMPILABLE-TYPES:SPECIFY.
∂13-Mar-89 0824 X3J13-mailer issue CONSTANT-COLLAPSING, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 08:24:21 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA18594; Mon, 13 Mar 89 09:22:09 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02093; Mon, 13 Mar 89 09:22:05 -0700
Date: Mon, 13 Mar 89 09:22:05 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131622.AA02093@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue CONSTANT-COLLAPSING, version 5
Forum: Compiler
Issue: CONSTANT-COLLAPSING
References: CLtL p. 78, 87
Issue CONSTANT-MODIFICATION
Issue CONSTANT-COMPILABLE-TYPES
Issue EQUAL-STRUCTURE
Issue QUOTE-SEMANTICS
Category: CHANGE
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 12 Dec 1988, Sandra Loosemore
V3, 03 Jan 1989, Sandra Loosemore
V4, 06 Jan 1989, Sandra Loosemore
V5, 11 Mar 1989, Sandra Loosemore
Status: Ready for release
Problem Description:
CLtL states that an implementation is permitted to "collapse" or
coalesce constants appearing in code to be compiled if they are EQUAL.
The definition of EQUAL does not permit coalescing of more general
isomorphic data structures (such as arrays and structures), which is
often desirable.
Issue QUOTE-SEMANTICS deals with whether coalescing may be performed
only by COMPILE-FILE, or by COMPILE and EVAL as well. If proposal
QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE passes, then coalescing could be
performed on all constants.
CLtL says: "An object is considered to be a constant in code to be
compiled if it is a self-evaluating form or contained in a QUOTE
form".
Proposal CONSTANT-COLLAPSING:GENERALIZE:
State the an implementation is permitted to coalesce constants
appearing in code to be compiled if they are equivalent under the
relationship defined in proposal CONSTANT-COMPILABLE-TYPES:SPECIFY.
Rationale:
There is little reason why implementations should not be allowed to
perform more general collapsing of structures, since the arguments
against doing so also apply to collapsing of EQUAL structures, which
is already permitted. The arguments for coalescing of EQUAL structures
(primarily space reduction) also apply to coalescing of structures that
are equivalent under a more general coalescing predicate.
Current Practice:
Both PSL/PCLS and A-Lisp collapse isomorphic arrays and structures,
and certain other data types that are defined internally as structures
(RANDOM-STATEs, for example). Lucid Common Lisp also uses a more
general coalescing predicate than EQUAL.
Cost to implementors:
None. This extends the range of permitted behavior for
implementations but does not require any implementation to change.
Cost to users:
Programs that depend on objects not being coalesced except when they
are EQUAL may break under this proposal. The only way one would be
able to detect that coalescing has taken place is if objects that were
not EQ in the source file become EQ after compilation; accessors on
the objects would return the same values regardless of whether or not
coalescing has taken place.
Benefits:
Collapsing of isomorphic arrays may lead to significant memory savings
in some applications.
Discussion:
This proposal depends heavily on issue CONSTANT-COMPILABLE-TYPES.
Some people believe that if the definition of EQUAL weren't "broken",
there wouldn't be any need for this proposal.
There is no inherent reason why the "coalescing predicate" must be the
same as the relationship used by the compiler/loader to construct
equivalent copies of objects of constants, but making the same rules
be applied in both situations simplifies the language somewhat.
∂13-Mar-89 0840 X3J13-mailer Issue: UNSOLICITED-MESSAGES
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 Mar 89 08:40:09 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Mon, 13 Mar 89 11:34:05 EST
Date: Mon, 13 Mar 89 11:35 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
Cc: chapman%aitg.DEC@decwrl.dec.com, x3j13@sail.stanford.edu
In-Reply-To: <890312191349.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-Id: <19890313163525.7.BARMAR@OCCAM.THINK.COM>
Date: Sun, 12 Mar 89 19:13 EST
From: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
I agree that this is an important issue.
I am not sure I agree with the proposed solution -- partly because
I don't think it goes nearly far enough, and partly because I think the
wording for the place where it stops encourages might actually encourage
more `abuse' than currently exists.
I think it should be possible to know with certainly that calling EQ,
CONS, or even COMPILE, was not going to do I/O, at least in
the normal case.
Do progress notes in the wholine count as output? If not, why not? If
so, are you proposing that they be prohibited? In Genera, calling
COMPILE displays "Compiling <name>" in the wholine, and calling
READ-CHAR on a console stream displays "User Input" in the wholine. I
like these things, but I think it will be difficult to express this
distinction in general enough terms in the standard.
In exceptional cases, CONS might produce GC warnings
or COMPILE might produce compiler warnings, but never should COMPILE
type out anything like
Compiling FOO.
or should EQ type out
Performing EQ comparison of #<FOO 32> and #<BAR 17>.
Right now, nothing assures me of this and I find that disturbing.
Why is this problem unique to Lisp? Is there any wording in the C
standard that explicitly prohibits malloc() from causing output? I
doubt it, yet I don't think they find this disturbing.
I think market forces should be enough to prevent really silly
unsolicited messages, just as all serious Lisp implementations have a GC
even though CLtL never mentions it.
barmar
∂13-Mar-89 0834 X3J13-mailer issue LOAD-TIME-EVAL, version 11
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 08:34:06 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA18990; Mon, 13 Mar 89 09:31:55 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02140; Mon, 13 Mar 89 09:31:50 -0700
Date: Mon, 13 Mar 89 09:31:50 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131631.AA02140@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue LOAD-TIME-EVAL, version 11
On this issue, we've come up with an improved version of the proposal that
was accepted at the January meeting.
Forum: Compiler
Issue: LOAD-TIME-EVAL
References: #, (p. 356), (EVAL-WHEN (LOAD) ...) (p. 69-70)
issue SHARP-COMMA-CONFUSION
Category: ADDITION
Edit history: 06-Jun-87, Version 1 by James Kempf
17-Jul-87, Version 2 by James Kempf
12-Nov-87, Version 3 by Pitman (alternate direction)
01-Feb-88, Version 4 by Moon
(from version 2 w/ edits suggested by Masinter)
06-Jun-88, Version 5 by Pitman
(fairly major overhaul, merging versions 3 and 4)
21-Sep-88, Version 6 by Moon (stripped down)
17-Oct-88, Version 7 by Loosemore (change direction again)
30-Dec-88, Version 8 by Loosemore (tweaks)
23-Jan-89, Version 9 by Loosemore (amendments)
02-Mar-89, Version 10 by Loosemore (new proposal)
11-Mar-89, Version 11 by Loosemore
Problem description:
Common Lisp provides reader syntax (#,) which allows the programmer
to designate that a particular expression within a program is to be
evaluated early (at load time) but to later be treated as a constant.
Unfortunately, no access to this capability is available to programs
which construct other programs without going through the reader.
Some computations can be deferred until load time by use of EVAL-WHEN,
but since EVAL-WHEN must occur only at toplevel, and since the nesting
behavior of EVAL-WHEN is quite unintuitive, EVAL-WHEN is not a general
solution to the problem of load-time computation of program constants.
Proposal R**2-NEW-SPECIAL-FORM was approved at the January 1989
meeting. After the meeting, some additional suggestions were made that
have been incorporated into proposal R**3-NEW-SPECIAL-FORM. The sections
of the two proposals that differ are marked with change bars in the margin.
Proposal (LOAD-TIME-EVAL:R**2-NEW-SPECIAL-FORM):
Add a new special form, LOAD-TIME-VALUE, which has the following
contract:
LOAD-TIME-VALUE form &optional read-only-p [Special Form]
LOAD-TIME-VALUE provides a mechanism for delaying evaluation of <form>
until the expression is in the "runtime" environment.
If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
| performs normal semantic processing such as macro expansion but
| arranges for the evaluation of <form> to occur at load time in a null
lexical environment, with the result of this evaluation then being
treated as an immediate quantity at run time. It is guaranteed that
the evaluation of <form> will take place only once when the file is
loaded, but the order of evaluation with respect to the "evaluation"
of top-level forms in the file is unspecified.
If a LOAD-TIME-VALUE expression appears within a function compiled
with COMPILE, the <form> is evaluated at compile time in a null lexical
environment. The result of this compile-time evaluation is treated as
an immediate quantity in the compiled code.
In interpreted code, <form> is evaluated (by EVAL) in a null
lexical environment, and one value is returned. Implementations which
implicitly compile (or partially compile) expressions passed to
EVAL may evaluate the <form> only once, at the time this
compilation is performed. This is intentionally similar to the
freedom which implementations are given for the time of expanding
macros in interpreted code.
| Note that, in interpreted code, there is no guarantee as to when
| evaluation of <form> will take place, or the number of times the
| evaluation will be performed. Since successive evaluations of the
| same LOAD-TIME-VALUE expression may or may not result in an evaluation
| which returns a "fresh" object, destructive side-effects to the
| resulting object may or may not persist from one evaluation to the
| next. It is safest to explicitly initialize the object returned by
| LOAD-TIME-VALUE, if it is later modified destructively.
| Implementations must guarantee that each reference to a
| LOAD-TIME-VALUE expression results in at least one evaluation of its
| nested <form>. For example,
| (DEFMACRO CONS-SELF (X)
| `(CONS ,X ,X))
| (CONS-SELF (LOAD-TIME-VALUE (COMPUTE-IT)))
| must perform two calls to COMPUTE-IT; although there is only one
| unique LOAD-TIME-VALUE expression, there are two distinct references
| to it.
|
| In the case of a LOAD-TIME-VALUE form appearing in a quoted expression
| passed to EVAL, each call to EVAL must result in a new evaluation of
| <form>. For example,
| (DEFVAR X 0)
| (DEFUN FOO () (EVAL '(LOAD-TIME-VALUE (INCF X))))
| is guaranteed to increment X each time FOO is called, while
| (DEFUN FOO () (LOAD-TIME-VALUE (INCF X)))
| may cause X to be evaluated only once.
The READ-ONLY-P argument designates whether the result can be considered
read-only constant. If NIL (the default), the result must be considered
ordinary, modifiable data. If T, the result is a read-only quantity
which may, as appropriate, be copied into read-only space and/or shared
with other programs. (Because this is a special form, this argument is
-not- evaluated and only the literal symbols T and NIL are permitted.)
Rationale:
LOAD-TIME-VALUE is a special form rather than a function or macro
because it requires special handling by the compiler.
Requiring the compiler to perform semantic processing such as macro
expansion on the nested <form>, rather than delaying all such processing
until load time, has the advantages that fewer macro libraries may need
to be available at load time, and that loading may be faster and result
in less consing due to macroexpansion. If users really want to delay
macroexpansion to load time, this can be done with an explicit call to
EVAL, e.g.
(LOAD-TIME-VALUE (EVAL '(MY-MACRO)))
Allowing the same LOAD-TIME-VALUE to cause its nested <form> to be
evaluated more than once makes simplifies its implementation in
interpreters which do not perform a preprocessing code walk. It also
makes the rules for the time of its processing analogous to those
for macro expansion.
This proposal explicitly does -not- tie LOAD-TIME-VALUE to the #,
read macro. Doing so would be an incompatible change to the definition
of #, (which is reliably useful only -inside- quoted structure,
while LOAD-TIME-VALUE must appear -outside- quoted structure in a
for-evaluation position).
The requirement that LOAD-TIME-VALUE expressions be evaluated once per
reference (rather than once per unique expression) prevents problems
that could result by performing destructive side-effects on a value
that is unexpectedly referenced in more than one place.
Proposal (LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM):
Add a new special form, LOAD-TIME-VALUE, which has the following
contract:
LOAD-TIME-VALUE form &optional read-only-p [Special Form]
LOAD-TIME-VALUE provides a mechanism for delaying evaluation of <form>
until the expression is in the "runtime" environment.
If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
| performs its normal semantic processing (such as macro expansion and
| translation into machine code) on the form, but arranges for the
| execution of <form> to occur at load time in a null
lexical environment, with the result of this evaluation then being
treated as an immediate quantity at run time. It is guaranteed that
the evaluation of <form> will take place only once when the file is
loaded, but the order of evaluation with respect to the "evaluation"
of top-level forms in the file is unspecified.
If a LOAD-TIME-VALUE expression appears within a function compiled
with COMPILE, the <form> is evaluated at compile time in a null lexical
environment. The result of this compile-time evaluation is treated as
an immediate quantity in the compiled code.
In interpreted code, <form> is evaluated (by EVAL) in a null
lexical environment, and one value is returned. Implementations which
implicitly compile (or partially compile) expressions passed to
EVAL may evaluate the <form> only once, at the time this
compilation is performed. This is intentionally similar to the
freedom which implementations are given for the time of expanding
macros in interpreted code.
| If the same (compared with EQ) list (LOAD-TIME-VALUE <form>) is
| evaluated or compiled more than once, it is unspecified whether <form>
| is evaluated only once or is evaluated more than once. This can
| happen both when an expression being evaluated or compiled shares
| substructure, and when the same expression is passed to EVAL or to
| COMPILE multiple times. Since a LOAD-TIME-VALUE expression may be
| referenced in more than one place and may be evaluated multiple times
| by the interpreter, it is unspecified whether each execution returns
| a "fresh" object or returns the same object as some other execution.
| Users must use caution when destructively modifying the resulting
| object.
|
| If two lists (LOAD-TIME-VALUE <form>) are EQUAL but not EQ, their
| values always come from distinct evaluations of <form>. Coalescing
| of these forms is not permitted.
The READ-ONLY-P argument designates whether the result can be considered
read-only constant. If NIL (the default), the result must be considered
ordinary, modifiable data. If T, the result is a read-only quantity
which may, as appropriate, be copied into read-only space and/or shared
with other programs. (Because this is a special form, this argument is
-not- evaluated and only the literal symbols T and NIL are permitted.)
Rationale:
LOAD-TIME-VALUE is a special form rather than a function or macro
because it requires special handling by the compiler.
Requiring the compiler to perform semantic processing such as macro
expansion on the nested <form>, rather than delaying all such processing
until load time, has the advantages that fewer macro libraries may need
to be available at load time, and that loading may be faster and result
in less consing due to macroexpansion. If users really want to delay
macroexpansion to load time, this can be done with an explicit call to
EVAL, e.g.
(LOAD-TIME-VALUE (EVAL '(MY-MACRO)))
Allowing the same LOAD-TIME-VALUE to cause its nested <form> to be
evaluated more than once makes simplifies its implementation in
interpreters which do not perform a preprocessing code walk. It also
makes the rules for the time of its processing analogous to those
for macro expansion.
This proposal explicitly does -not- tie LOAD-TIME-VALUE to the #,
read macro. Doing so would be an incompatible change to the definition
of #, (which is reliably useful only -inside- quoted structure,
while LOAD-TIME-VALUE must appear -outside- quoted structure in a
for-evaluation position).
Allowing multiple references to the same LOAD-TIME-VALUE expression
to result in only one interpretation allows it to be specified more
cleanly. It also allows interpreters that do not perform a prepass
to cache LOAD-TIME-VALUE expressions.
Current Practice:
This is an addition to the language and has not yet been implemented.
Cost to Implementors:
In compiled code, (LOAD-TIME-VALUE <form>) is similar to
'#,<form>. Most implementations can probably make use of the same
mechanism they use to handle #, to handle LOAD-TIME-VALUE. Note that
#, does not currently provide a mechanism for dealing with
non-read-only-ness.
Implementing LOAD-TIME-VALUE in the interpreter should be fairly
straightforward, since one simply needs to evaluate the <form> in the
null lexical environment. Implementations that use a preprocessing
code walk in the interpreter to perform macro expansion could process
LOAD-TIME-VALUE forms at that time.
Some code-walkers would have to be taught about this new
special form. Such changes would likely be trivial.
Cost to Users:
Some code-walkers would have to be taught about this new
special form. Such changes would likely be trivial.
Benefits:
Users are given a mechanism that to force evaluation to be delayed
until load time that does not rely on a feature of the reader.
Discussion:
Earlier versions (up to version 7) of this proposal stated that
all semantic processing of the LOAD-TIME-VALUE form should be postponed
until load time.
The semantics of LOAD-TIME-VALUE would be simplified considerably if
the READ-ONLY-P argument were removed and destructive operations on
the result of evaluating <form> prohibited. However, some people feel
that the ability to destructively modify the value is an essential
feature to include.
"Collapsing" of multiple references to the same LOAD-TIME-VALUE
expression could be allowed for read-only situations, but it seems
like it would be more confusing to make it legal in some situations
and not in others.
A number of other alternatives have been considered on this issue,
including:
- A proposal for a new special form that would force evaluation of
the <form> to happen only once. This was rejected because of
implementation difficulties.
- A proposal to add a function making the "magic cookie" used by #,
available to user code. The current proposal does not prevent such
a function from being added, but this approach appeared to have
less support than making the hook available as a new special form.
- A proposal to remove #, entirely (issue SHARP-COMMA-CONFUSION).
- A suggestion to change the behavior of (EVAL-WHEN (LOAD) ...).
Kent Pitman says:
Although I'm willing to take multiple evaluation in the interpreter
as a compromise position, I would like it mentioned in the discussion
that this was only an expedient to getting this issue accepted at all,
and that I'm not really happy about it. I have said that I think a
number of our lingering problems (with EVAL-WHEN, COMPILER-LET, and
this -- for example) are due to the presence of interpreters which do
not do a semantic-prepass at a known time. If I had my way, we would
require a semantic pre-pass and we would then be able to forbid
multiple evaluations even in the interpreter.
Moon and Gray support proposal R**3-NEW-SPECIAL-FORM.
Pitman also expressed willingness to go along with
R**3-NEW-SPECIAL-FORM, but was somewhat concerned that coalescing
LOAD-TIME-VALUE results based on EQ-ness of the LOAD-TIME-VALUE form
could conceivably lead to trouble down the line. However, since he
could provide no actual examples to back up that worry, and since the
majority opinion was that some implementations would find a
restriction against such coalescing an undue burden, the decision was
made to just `note the concern' and proceed on. Sandra Loosemore and
JonL White concur with this position.
∂13-Mar-89 0853 X3J13-mailer issue COMPILER-VERBOSITY, version 6
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 Mar 89 08:53:16 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Mon, 13 Mar 89 11:48:42 EST
Date: Mon, 13 Mar 89 11:50 EST
From: Barry Margolin <barmar@Think.COM>
Subject: issue COMPILER-VERBOSITY, version 6
To: cl-compiler@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131546.AA02078@defun.utah.edu>
Message-Id: <19890313165001.9.BARMAR@OCCAM.THINK.COM>
I see the benefit of :PRINT, but do we really need :VERBOSE? What's the
difference between
(compile path :verbose t)
and
(format t "~&Compiling file ~A...~%" path)
(compile-file path)
(format t "~&done.~%")
If any users want to have this controlled by a global variable, they can
do what we (Thinking Machines) did years ago and package it up in their
own function. At this stage of the game I don't see the need to add
gratuitous features like this.
:PRINT is less gratuitous because it implements a feature that the user
can't add himself.
barmar
∂13-Mar-89 0855 X3J13-mailer Issue: UNSOLICITED-MESSAGES
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Mar 89 08:54:56 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 555652; Mon 13-Mar-89 11:51:33 EST
Date: Mon, 13 Mar 89 11:51 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: barmar@Think.COM
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, chapman%aitg.DEC@decwrl.dec.com,
x3j13@sail.stanford.edu
In-Reply-To: <19890313163525.7.BARMAR@OCCAM.THINK.COM>
Message-ID: <890313115113.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Mon, 13 Mar 89 11:35 EST
From: Barry Margolin <barmar@Think.COM>
Date: Sun, 12 Mar 89 19:13 EST
From: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
I agree that this is an important issue.
I am not sure I agree with the proposed solution -- partly because
I don't think it goes nearly far enough, and partly because I think the
wording for the place where it stops encourages might actually encourage
more `abuse' than currently exists.
I think it should be possible to know with certainly that calling EQ,
CONS, or even COMPILE, was not going to do I/O, at least in
the normal case.
Do progress notes in the wholine count as output? If not, why not? ...
No. They are passive. The function in question does not output to the
wholine. Rather, it arranges information such that a foreign process
can access it and display it. For example, if 500 calls to LOAD are done
in three second, you don't always get 500 progress messages. That is
because the output is done by the foreign process doing the polling and
not the process which is running the CL code. I think this distinction
is important. Indeed, if the running process could block, signal an
error, etc. due to problems in I/O then it would not be a good idea.
If so, are you proposing that they be prohibited?
No.
In Genera, calling
COMPILE displays "Compiling <name>" in the wholine, and calling
READ-CHAR on a console stream displays "User Input" in the wholine.
No. COMPILE does no display. A foreign process which is working by polling
does. This is no different than a foreign process doing any kind of
debugging activity.
I like these things, but I think it will be difficult to express this
distinction in general enough terms in the standard.
I don't think it's that difficult.
In exceptional cases, CONS might produce GC warnings
or COMPILE might produce compiler warnings, but never should COMPILE
type out anything like
Compiling FOO.
or should EQ type out
Performing EQ comparison of #<FOO 32> and #<BAR 17>.
Right now, nothing assures me of this and I find that disturbing.
Why is this problem unique to Lisp? Is there any wording in the C
standard that explicitly prohibits malloc() from causing output? I
doubt it, yet I don't think they find this disturbing.
Maybe it's because C people have traditionally been willing to settle
for less. :-) Seriously, I think it's a clear hole in their standard.
People would probably flame if things that weren't documented as doing
I/O were to suddenly start doing it.
I think market forces should be enough to prevent really silly
unsolicited messages,
Really I don't. COMPILE is a notable offender. Real implementations have
been known to print "Compiling FOO." on *TERMINAL-IO* and this proposal
does not forbid it.
In some cases, market pressure can --- after some number of months --
get things back in line. In others, implementors just point to the standard
and either say "it doesn't say anything" or even worse suggest that the
reason it doesn't say it is because it wants to leave room.
Not all implementors come from our culture. Often, those that don't
would -prefer- to have little `hints' (rules?) like this specified so
that the process of making incidental decisions would be easier. For
example, it's not unreasonable that implementors find themselves asking
"Should COMPILE say something?" -- It's been traditional for compilers
in languages where you couldn't invoke the compiler at runtime to do
typeout, so they might naturally assume that the same should be true
here. Certainly it's natural for them to at least answer the question.
just as all serious Lisp implementations have a GC
even though CLtL never mentions it.
This comes up because it's a "hard issue" and new implementors naturally
tend to discuss "hard issues" with other implementors before even getting
started. My guess is that no new implementor would consider calling up
Moon or JonL or Masinter to ask what the I/O behavior of COMPILE should
be. Probably they would just make a guess, hope it was right, and move on
to the next seemingly trivial decision.
∂13-Mar-89 0853 X3J13-mailer issue MACRO-CACHING, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 08:49:54 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA19529; Mon, 13 Mar 89 09:47:42 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02151; Mon, 13 Mar 89 09:47:38 -0700
Date: Mon, 13 Mar 89 09:47:38 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131647.AA02151@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue MACRO-CACHING, version 2
Issue: MACRO-CACHING
Forum: Compiler
References: 8.2 Macro Expansion (CLtL pp151-152),
Issues PACKAGE-CLUTTER, LISP-SYMBOL-REDEFINITION,
QUOTE-SEMANTICS (a.k.a. QUOTE-MAY-COPY),
and MACRO-ENVIRONMENT-EXTENT
Category: Clarification
Edit history: 31-Jan-89, Version 1 by Pitman
11-Mar-89, Version 2 by Loosemore (add discussion)
Status: Ready for release
Background:
CLtL suggests that macro caching is a legitimate strategy.
Two particular kinds of caching are common:
Displacement. A macro expansion function displaces the actual macro in
order to avoid any later need for lookup.
Table. A macro expression is looked up in a cache (such as a hash table)
to avoid having to run the expander code.
While CLtL seems to expressly suggest these strategies to be legitimate,
linguistic constraints show that in most cases they are not. The problems
are things like:
- lexical scoping (MACROLET and SYMBOL-MACROLET, and FLET and LET to
the extent that they shadow the effect of MACROLET and SYMBOL-MACROLET,
respectively).
- ``read only'' structure
To see the problem, consider the following examples:
(SETQ FOO1 '(FOO))
(EVAL `(LIST (MACROLET ((FOO (&WHOLE FORM) '(+ 1 1))) ,FOO1)
(MACROLET ((FOO (&WHOLE FORM) '(+ 1 2))) ,FOO1)))
=> (2 3)
Note that because the lexical contour may vary for an EQL expression,
however, displacing the expansion will cause confusion:
(DEFUN DISPLACE (X Y)
(SETF (CAR X) (CAR Y))
(SETF (CDR X) (CDR Y))
X)
(DEFVAR FOO2 '(FOO))
(EVAL `(LIST (MACROLET ((FOO (&WHOLE FORM)
(DISPLACE FORM '(+ 1 1)))) ,FOO2)
(MACROLET ((FOO (&WHOLE FORM)
(DISPLACE FORM '(+ 1 2)))) ,FOO2)))
=> (2 2)
CLtL suggests that a displacement hook might be placed in
*MACROEXPANSION-HOOK*. The above example shows that to be an
unreliable technique.
If this were not enough, displacement is also inappropriate because
no Common Lisp primitive can tell the difference between regular list
structure and read-only list structure. Since a macro form being
expanded might have been read-only in some implementations (e.g., EVAL
of a quoted list), the macro cannot reliably side-effect the structure.
In the case of table-lookup, the problem is more complicated.
Table-lookup does not have a necessary effect beyond the particular
lookup being done at the moment. To do table-lookup correctly relies
on the key being not only the expression but also the lexical
environment object. Whether the cost of making and throwing away so
many tables was worth the savings over running the macro expander is
not at all clear. And the GC effects of caching every macro environment
ever seen may be extraordinary, however correctness could in principle
be preserved by doing such a two-dimensional lookup... at least unless
we decide that macro environments have only dynamic extent. [A separate
proposal, MACRO-ENVIRONMENT-EXTENT, addresses this issue. If it passed,
then there would really be no way for users to do reliable macro caching
without cooperation from the system to have the cache be part of the
environment itself.]
Problem Description:
Macro caching by displacement is provably not semantically valid.
Macro caching by table lookup is difficult for a user to do correctly,
and in any case is not possible to handle efficiently in user code.
Proposal (MACRO-CACHING:DISALLOW):
1. a. Clarify that macro caching by displacement is not semantically
valid in user code.
b. Clarify that macro caching by displacement is semantically valid
for system macros and special forms, provided that such caching
does not prejudice the expansion of user-code contained in any
displaced code. For example:
(PROG () (FOO))
could displace to a BLOCK, but the (FOO) must appear un-expanded
in the BLOCK in case the BLOCK occurs in more than one lexical
environment.
2. a. Clarify that macro caching by table lookup is not semantically
valid in user code in order to correctly respect the lexical
environment.
Implementations are free to extend the language to permit such
lookup and to offer functions which support it in a more efficient
way, but code using such functions would, of course, not be portable.
b. Clarify that macro caching by table lookup is valid for the system,
but only if it correctly respects the lexical environment.
Proposal (MACRO-CACHING:RESTRICT):
Like DISALLOW, but change 2a to:
Clarify that macro caching by table lookup is semantically valid only
if the lookup is keyed both on the form and the environment.
Implementations are free to extend the language to offer functions
which support it in a more efficient way, but code using such functions
would, of course, not be portable.
Rationale:
1. a. Displacement has effects which by their nature transcend
lexical boundaries.
b. The system can assure that lexical boundaries are irrelevant in some
cases because users are not permitted to redefine or shadow definitions
in the initial LISP system. [See issues PACKAGE-CLUTTER and
LISP-SYMBOL-REDEFINITION.]
2. a. Users can only associate an environment with a macro cache table
in a very clumsy way. Also, Permitting them to do so at all forces
macro environments to have indefinite extent, and works against
efficiency in compilers.
b. The system is capable of allocating space in an environment object
for a macro cache which can be reliably kept up in synch with the
lexical environment environment.
Test Case:
;; #1: File compiling this definition in some implementations will produce
;; a definition that returns read-only list structure. The call to EVAL
;; on the result must not try to modify the read-only structure during
;; macroexpansion. [See issue QUOTE-SEMANTICS.]
(DEFUN READ-ONLY-FOO () '(MACROLET ((FOO (&WHOLE FORM) (+ 1 1))) (FOO)))
(EVAL (READ-ONLY-FOO))
=> 2
;; #2: This constructs a form and then uses it in two places in another
;; constructed form. Each of the uses is in a different lexical
;; contour, so must be expanded differently.
(LET ((FOO (LIST 'FOO)))
(EVAL `(LIST (MACROLET ((FOO (&WHOLE FORM) '(+ 1 1))) ,FOO)
(MACROLET ((FOO (&WHOLE FORM) '(+ 1 2))) ,FOO))))
=> (2 3)
;; #3: This is effectively the same thing but involves a MACROLET
;; shadowing a DEFMACRO rather than two MACROLETs, since some
;; implementations might only be caching expansions that come
;; from DEFMACRO.
(DEFMACRO FOO (&WHOLE FORM) '(+ 1 1))
(LET ((FOO (LIST 'FOO)))
(EVAL `(LIST ,FOO (MACROLET ((FOO (&WHOLE FORM) '(+ 1 2))) ,FOO))))
=> (2 3)
Current Practice:
Symbolics Genera does not use displacing or table caching in either
the interpreter or compiler.
Symbolics Cloe, a compiled only implementation, uses table caching
to boost compilation by a little. Running the test cases above turned
up a bug (in test case #3), which is now in the process of being fixed.
[The fact that a bug was turned up in code written by a CL implementor
is an existence proof that the potential for trouble was not imagined.]
Both Symbolics Cloe and Symbolics Genera support *MACROEXPANSION-HOOK*,
leaving open the possibility of users bringing disasters upon themselves.
Macro environment objects in Symbolics Genera are stack-allocated, so
have only dynamic extent.
Cost to Implementors:
This proposal is upward compatible with correct implementations.
Cost to Users:
There is no cost to users of the RESTRICT proposal, unless they were doing
semantically invalid caching.
The cost to users of the DISALLOW proposal is a loss of speed in some cases
which are semantically valid. In general, however, the efficiency and
usefulness of such caching is subject to question in code intended to be
ported. Given that implementations are not required to ever give the same
environment object twice, the caching may be all for naught in some
implementations.
Cost of Non-Adoption:
Continued widespread confusion about whether displacement is a legitimate
implementation technique for user code.
Benefits:
Since *MACROEXPANSION-HOOK* is in the Lisp package, multiple applications
in the same environment share its effects. Often one application will
clobber another's hook, or introduce a hook that is not desirable to other
applications when none previously existed. Since a common use of
*MACROEXPANSION-HOOK* is to install a macro caching mechanism, clarifying
the situations in which *MACROEXPANSION-HOOK* should not be used will
decrease the likelihood of one program breaking, slowing down, or otherwise
adversely affecting another.
Aesthetics:
Most people agree that macro caching techniques are only supposed to improve
speed without affecting semantics. This proposal is only intended to
underscore that necessary truth. Insofar as this is only a clarification,
it presumably has no significant aesthetic impact.
Discussion:
Pitman thinks it's a good idea to clarify this issue because it's not really
spelled out now and it's the sort of thing programmers can waste a lot of
time bickering about to no good end. Either the functionality is reliable
and should be encouraged, or it is not reliable and should be discouraged
or forbidden. Pitman supports the DISALLOW proposal because it leaves open
the possibility of making macro environments have dynamic extent, but he
can live with the RESTRICT position, which he believes represents the
status quo.
Bob Laddaga (a Cloe maintainer who reviewed a draft of this proposal)
supports the DISALLOW option as well.
David Grays says:
I can accept MACRO-CACHING:DISALLOW.
The Explorer evaluator does displacement of macros, but is careful to
correctly handle the cases exemplified in your test cases #1 and #2.
It does not do the right thing for #3, but that is a bug that can fairly
easily be fixed.
Sandra Loosemore says:
This issue is closely tied to MACRO-ENVIRONMENT-EXTENT. If we decide
environments have (or can be made to have) indefinite extent, I see no
reason not to go with MACRO-CACHING:RESTRICT. On the other hand, if
we decide environments have only dynamic extent, proposal
MACRO-CACHING:DISALLOW is the only one that makes sense.
∂13-Mar-89 0924 X3J13-mailer issue QUOTE-SEMANTICS, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 09:23:57 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA20995; Mon, 13 Mar 89 10:21:38 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02184; Mon, 13 Mar 89 10:21:33 -0700
Date: Mon, 13 Mar 89 10:21:33 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131721.AA02184@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue QUOTE-SEMANTICS, version 2
This issue replaces QUOTE-MAY-COPY, which was distributed and discussed
briefly at the last meeting.
Forum: Compiler
Issue: QUOTE-SEMANTICS
Subsumes: Issue QUOTE-MAY-COPY
References: CLtL p. 55, 78, 86, 143
Issue CONSTANT-COLLAPSING
Issue CONSTANT-COMPILABLE-TYPES
Issue CONSTANT-CIRCULAR-COMPILATION
Category: CLARIFICATION
Edit History: V1, 22 Jan 1989, Sandra Loosemore
V2, 13 Mar 1989, Sandra Loosemore (discussion)
Status: Ready for release
Problem Description:
Is it permissible for COMPILE and EVAL to coalesce or copy constants?
Are there constraints upon what kinds of objects may appear as
constants in code processed by COMPILE or EVAL, similar to those for
COMPILE-FILE?
CLtL p86 states that (QUOTE <x>) simply returns <x>. On p55 it is
mentioned that the only self-evaluating forms that may be copied are
numbers or characters. It is also stated that an implementation is
permitted to collapse (or coalesce) EQUAL constants "appearing in code
to be compiled" (p78), which is defined to mean self-evaluating forms
or objects contained in a QUOTE form (without reference to whether the
form is processed by EVAL, COMPILE, or COMPILE-FILE).
Because of its nature as a file processor, COMPILE-FILE generally must
cause copies of constants to be constructed when the compiled code is
loaded. In a number of existing Lisp implementations, COMPILE also
causes constant objects to be copied and/or coalesced. There is also
at least one implementation where constants are copied by EVAL in some
circumstances.
Proposal QUOTE-SEMANTICS:NO-COPYING:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is not permitted; the resulting program
must reference objects that are EQL to the corresponding objects in
the source code. The constraints on what kinds of objects may appear
as constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.
Rationale:
This proposal is consistent with what many people think of as the
"traditional" semantics for QUOTE. It gives users maximum flexibility
about what kinds of objects may appear as constants.
Proposal QUOTE-SEMANTICS:COPYING-ALLOWED-BUT-NO-CONSTRAINTS:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted. Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime. Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.
Any object may validly appear as a constant in code processed by EVAL
or COMPILE. The constraints on what kinds of objects may appear as
constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.
Rationale:
This proposal is the most consistent with the semantics stated in CLtL.
It gives users maximum flexibility about what kinds of objects may
appear as constants.
Proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted. Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime. Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.
The constraints on what kinds of objects may appear as constants
(described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply to EVAL and COMPILE as well as to
COMPILE-FILE.
Rationale:
This makes the rules for handling of constants consistent between
EVAL, COMPILE, and COMPILE-FILE. It gives implementors maximum
flexibility in handling constants in EVAL and COMPILE.
Current Practice:
Implementations in which COMPILE attempts to copy all constants
include PSL/PCLS and Kyoto Common Lisp.
In Lucid Common Lisp, constants are not normally copied by COMPILE,
but since COMPILE does coalesce constants, it may cause QUOTE to
return an object which is not EQL to the object which appeared in the
source code.
Symbolics Genera has COMPILE copy list, string, non-displaced array,
and (I-Machine only) closure constants, but Moon says he thinks this
is wrong.
There is known to be at least one implementation where expanding the
DEFUN macro causes all constants in the body of the function to be
copied.
Cost to implementors:
Proposal NO-COPYING would involve a significant cost in those
implementations where constants are now copied or coalesced by EVAL
and COMPILE. Some implementations would also require substantial
changes to support proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS. The
aspect that is likely to cause the most problems is that, in some
implementations, the garbage collector assumes that constants
referenced in compiled code have been copied to read-only storage and
do not need to be scanned or relocated.
Proposal SAME-AS-COMPILE-FILE has no adoption cost above what is
required to support issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION.
Cost to users:
Proposals COPYING-ALLOWED-BUT-NO-CONSTRAINTS and SAME-AS-COMPILE-FILE
may break some existing programs that assume constants in code
processed by EVAL or COMPILE are always EQL to the corresponding
objects in the source code. Proposal SAME-AS-COMPILE-FILE may also
break existing programs that depend on referencing "undumpable"
constants in code processed by EVAL or COMPILE. In both cases,
however, the behavior is already nonportable. Both proposals would
permit implementations in which these programs now work to continue to
provide their existing behavior.
Benefits:
The semantics of QUOTE are clarified.
Discussion:
This issue subsumes issue QUOTE-MAY-COPY, which caused a very lengthy
debate on the cl-compiler mailing list.
This issue relates to conformance requirements. Accepting either of
proposals NO-COPYING or COPYING-ALLOWED-BUT-NO-CONSTRAINTS would mean
that not all conforming programs could be compiled with COMPILE-FILE.
Some people may find this disturbing, particularly since one of the
goals of Common Lisp has been to try to eliminate differences in
semantics between compiled and interpreted code.
Loosemore supports proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE,
since it requires essentially no conversion cost for implementors and
does not break any user programs that are not already nonportable.
JonL White says:
Since we have already passed the proposal that permits constants to
be "read-only" -- it is an error to modify them -- and have already
passed the proposal that allows access to updateable structures --
LOAD-TIME-EVAL -- then there is no excuse for being overly concerned
with the storage address of quoted data. People who have mistakenly
used structured constants as updatable data should convert over to
either LOAD-TIME-EVAL or DEFPARAMETER.
Kent Pitman says:
The problem is that a lot of copying advocates have been going around
trying to use "the need for copying" as leverage for restricting
the set of things which I may quote. My view is that it is my write [sic]
to quote whatever I want, and it's up to the person who thinks they
can do something fun with copying to not get themselves in deeper than
they can handle.
Jeff Dalton says:
I would agree [with Pitman's remarks] too. My only quibble is that
it's not just "the need for copying" that's used a lever.
"Consistency with file compilation" is also being used as a lever.
∂13-Mar-89 0929 X3J13-mailer issue SAFE-CODE, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 09:29:10 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA21179; Mon, 13 Mar 89 10:26:59 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02193; Mon, 13 Mar 89 10:26:56 -0700
Date: Mon, 13 Mar 89 10:26:56 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131726.AA02193@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue SAFE-CODE, version 1
Issue: SAFE-CODE
Forum: Compiler
References: OPTIMIZE declaration (p160),
Issue ERROR-TERMINOLOGY
Category: CLARIFICATION/CHANGE
Edit history: 07-Mar-89, Version 1 by Pitman
Status: Ready for release
Problem Description:
The new error terminology refers to ``safe code'' in the definition
of the term and CLtL refers to
individual meanings of OPTIMIZE qualities, but there is no standardized
way of relating the two concepts.
Proposal (SAFE-CODE:SAFETY-3):
Define that, formally, the term ``safe code'' is code refers to any
code in which the OPTIMIZE quality for SAFETY has a value of 3.
Implementors might wish to consider treating other situations as safe
as well, but in making that decision both the relative values of other
OPTIMIZE qualities and the idiosyncratic properties of the particular
implementation should also be taken into account.
Examples:
1. The body of the following is safe...
a. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 3))) . body)
b. (LOCALLY (DECLARE (OPTIMIZE SAFETY )) . body)
2. The body in each of the following is unsafe. They might
or might not be treated as safe, possibly depending
on the values of other qualities and specifics of the
implementation.
a. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 0))) . body)
b. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 1))) . body)
c. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 2))) . body)
Rationale:
Programmers will probably intuitively expect that the term
``highest safety'' refers to giving the SAFETY quality its
highest safety.
Current Practice:
Implementors ...
Symbolics Genera does error checking always, and ignores OPTIMIZE
declarations.
Symbolics Cloe heeds OPTIMIZE declarations, but effectively makes
`judgment calls' in every case because there is no clear guidance
on how to interpret them.
Programmers ...
Many programmers write (DECLARE (SPEED 0) (SAFETY 3)) even when all
they really want to control is SAFETY because they are afraid that
unless they explicitly sacrifice speed, the compiler will ignore
their plea for error checking.
Cost to Implementors:
Some implementations might require a lot of nitpicky little changes.
Cost to Users:
Technically none. No portable code can really rely on much of any
reliable effect out of any of the OPTIMIZE qualities. However, some
users may rely on implementation-specific features of implementations,
and if those implementations are forced to change, non-portable user
code might break in some ways.
Cost of Non-Adoption:
The meaning of ``safe code'' will not be clearly defined.
Benefits:
Programmers will be able to say what they mean. They can stop
superstitiously putting (SPEED 0) next to (SAFETY 3) just to
assure they get safe code.
Aesthetics:
Improved. This will make the English align well with the code.
Discussion:
It is very important that we reach consensus in some form on this issue.
Pitman supports SAFE-CODE:SAFETY-3.
∂13-Mar-89 1014 X3J13-mailer Issue: UNSOLICITED-MESSAGES
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 Mar 89 10:14:33 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Mon, 13 Mar 89 13:09:40 EST
Date: Mon, 13 Mar 89 13:10 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
Cc: chapman%aitg.DEC@decwrl.dec.com, x3j13@sail.stanford.edu
In-Reply-To: <890313115113.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-Id: <19890313181059.0.BARMAR@OCCAM.THINK.COM>
Date: Mon, 13 Mar 89 11:51 EST
From: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
Date: Mon, 13 Mar 89 11:35 EST
From: Barry Margolin <barmar@Think.COM>
Do progress notes in the wholine count as output? If not, why not? ...
No. They are passive. The function in question does not output to the
wholine. Rather, it arranges information such that a foreign process
can access it and display it. For example, if 500 calls to LOAD are done
in three second, you don't always get 500 progress messages. That is
because the output is done by the foreign process doing the polling and
not the process which is running the CL code. I think this distinction
is important. Indeed, if the running process could block, signal an
error, etc. due to problems in I/O then it would not be a good idea.
So, the acceptability of progress notes has nothing to do with the
stream they are displayed on, only the fact that they are displayed by a
background process? This implies that a single-tasking machine that
displayed progress notes synchronously would therefore be unacceptable.
I find this distinction extremely arbitrary, since it is based only on
the implementation, not the program-visible effects.
I like these things, but I think it will be difficult to express this
distinction in general enough terms in the standard.
I don't think it's that difficult.
We'll have to come up with a general definition of passive output versus
active output. And we'll still have to make sure that passive output
isn't allowed to go to *STANDARD-OUPTUT*.
Why is this problem unique to Lisp? Is there any wording in the C
standard that explicitly prohibits malloc() from causing output? I
doubt it, yet I don't think they find this disturbing.
Maybe it's because C people have traditionally been willing to settle
for less. :-) Seriously, I think it's a clear hole in their standard.
People would probably flame if things that weren't documented as doing
I/O were to suddenly start doing it.
Actually, I think the difference is that Common Lisp includes some
operations that are not traditionally included in runtime libraries,
COMPILE, COMPILE-FILE, and LOAD being the most notable ones. No
Lisp implementor would even think of having CONS or EQ produce output,
just as the C standard doesn't need to say that malloc() is silent.
Perhaps this means that since we have such unusual runtime facilities,
we can't rely on common sense as other languages do. I would be willing
to support a blanket statement that said that no output may be produced
by functions other than that specified in the standard or due to the
signalling of conditions detected by the function.
Would this prevent an implementation from having a *DEBUG-CONS* variable
that turns on debugging output by CONS?
barmar
∂13-Mar-89 1046 X3J13-mailer Issue: UNSOLICITED-MESSAGES
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Mar 89 10:46:36 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 555842; Mon 13-Mar-89 13:43:40 EST
Date: Mon, 13 Mar 89 13:43 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: x3j13@sail.stanford.edu
cc: barmar@Think.COM, KMP@STONY-BROOK.SCRC.Symbolics.COM,
chapman%aitg.DEC@decwrl.dec.com
In-Reply-To: <890313115113.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-ID: <890313134321.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
[Further discussion on this topic will take place on CL-Editorial.]
∂13-Mar-89 1450 X3J13-mailer **DRAFT** issue CLOS-MACRO-COMPILATION, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 14:50:22 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA07805; Mon, 13 Mar 89 15:48:10 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02496; Mon, 13 Mar 89 15:48:08 -0700
Date: Mon, 13 Mar 89 15:48:08 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132248.AA02496@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue CLOS-MACRO-COMPILATION, version 2
This issue is still under discussion. There has been a lot of talk
about how this relates to the creation of meta-objects at compile
time, but the only proposals that have been made so far are the two
included here.
Forum: Compiler
Issue: CLOS-MACRO-COMPILATION
References: CLOS chapters 1 & 2 (88-002R)
CLOS chapter 3 (89-003)
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CLARIFICATION
Edit History: V1, 10 Mar 1989, Sandra Loosemore
V2, 13 Mar 1989, Sandra Loosemore
Status: **DRAFT**
Problem Description:
Do the CLOS defining macros (DEFCLASS, DEFMETHOD, DEFGENERIC, and
DEFINE-METHOD-COMBINATION) have compile-time side-effects similar
to those for DEFSTRUCT or DEFMACRO?
A part of the problem is that we do not currently have a full
understanding of all the issues involved. In particular, work on
defining the CLOS meta-object protocol is still in progress. The goal
of this proposal is to say enough about the behavior of these macros
in the standard so that users can use them portably in compiled code,
but to leave as much of the behavior as possible unspecified to avoid
placing undue restrictions on the meta-object protocol.
There are two proposals, MINIMAL and NOT-SO-MINIMAL.
Proposal CLOS-MACRO-COMPILATION:MINIMAL:
State that top-level calls to the CLOS defining macros have the
following compile-time side-effects. Any other compile-time behavior
is explicitly left unspecified.
DEFCLASS:
* The class name becomes a type specifier which may appear in
subsequent type declarations.
* The class name can be used to name a superclass in a subsequent
DEFCLASS.
* The class name can be used as a specializer in a subsequent
DEFMETHOD.
DEFGENERIC:
* The generic function can be referenced in a subsequent DEFMETHOD.
* The generic function is not callable at compile-time.
DEFMETHOD:
* The method is not callable at compile-time. If there is a generic
function with the same name at compile-time, compiling a DEFMETHOD
will not add the method to that generic function. The compiler may
perform tests for lambda-list congruence only between the DEFGENERICs
and DEFMETHODs for a given generic function name that appear within
the file being compiled, and not against a generic function of the
same name which exists in the compile-time environment.
DEFINE-METHOD-COMBINATION:
* The method combination can be used in a subsequent DEFGENERIC. If it
is referenced, the body of a long form of method combination must be
evaluable at compile-time.
Rationale:
The compile-time behavior of DEFCLASS is similar to DEFSTRUCT or
DEFTYPE.
DEFGENERIC and DEFMETHOD are similar to DEFUN, which doesn't add the
function definition to the compile-time environment. Since generic
functions may be freely redefined between compile and run time (just
like any other function), a method may end up "belonging" to a
different generic function at load time than at compile time.
Some implementations compose effective methods at compile time, which
requires evaluating the body of the DEFINE-METHOD-COMBINATION at
compile time.
Proposal CLOS-MACRO-COMPILATION:NOT-SO-MINIMAL:
This is the same as proposal MINIMAL, except under DEFCLASS add:
* The class may be instantiated at compile-time. Provided the
appropriate methods are also defined at compile-time, this implies:
- The class can be used as the :METACLASS option of a later DEFCLASS.
- It can be used as the :GENERIC-FUNCTION-CLASS or :METHOD-CLASS option
of a DEFGENERIC, GENERIC-FUNCTION, GENERIC-FLET, or GENERIC-LABELS.
Rationale:
Being able to instantiate a class at compile-time is somewhat more
convenient for users.
Current Practice:
The items listed under DEFCLASS in proposal MINIMAL are fairly standard
programming style.
Flavors does not support compile-time instantiation of classes. It
does not make method combinations available at compile-time either, but
Moon considers that to be a bad design choice.
Cost to implementors:
Unknown.
Cost to users:
Unknown, but probably fairly small.
Note that for proposal NOT-SO-MINIMAL, users still have to ensure that
any methods on the class which may be invoked at compile-time are
fully defined. This includes the INITIALIZE-INSTANCE and
SHARED-INITIALIZE methods that are invoked by MAKE-INSTANCE.
Wrapping an (EVAL-WHEN (EVAL COMPILE LOAD) ...) around the appropriate
definitions will make sure they are fully defined at compile-time.
Alternatively, the definitions could be placed in a separate file,
which is loaded before compiling the file that depends on those
definitions.
Benefits:
Programmers can rely on programs that use the CLOS defining macros
being able to compile correctly in all implementations, without having
to wrap explicit EVAL-WHENs around every macro call.
Discussion:
This writeup is based on discussions between Moon, Gray, and
Loosemore, who are mostly in agreement on the things presented in
proposal MINIMAL. We have purposely avoided saying anything about
whether meta-objects representing the classes, methods, etc. get
created at compile-time, or whether such meta-objects are fully or
partially defined. The basic questions addressed by this issue are
what kinds of things can be defined and then used during compilation
of the same file that defines them, and what restrictions might apply.
These proposals are not completely compatible with the meta-object
protocol document (89-003). Gregor Kiczales says:
No one believes that what is written in draft 10 of the MOP is valid.
Sandra Loosemore says:
Although I admit I don't understand all of the issues involved with
the meta-object protocol, I prefer proposal MINIMAL over
NOT-SO-MINIMAL. I don't think leaving the issue of whether or not
classes can be instantiated at compile-time unspecified places an
undue burden on users, and it does leave more freedom for the
meta-object protocol to decide what the right behavior really is.
Dick Gabriel notes:
The question I have about the process going on with respect to the
CLOS-MACRO-COMPILATION issue is whether the fine-grained behavior of
CLOS under various compilation/evaluation situations is being
over-specified.
At this stage of the game I worry that we might go a little too far in
one direction in specification when we are actually engaged in design
work. This isn't intended to be a criticism of any committees, but I
would feel a lot more comfortable with a conservative specification
that defined well-formed programs being loaded or compiled in fresh
Common Lisps with a pretty simple eval-when model that is easier to
specify and which makes it easy for all but the hairiest
compilation-environment-frobbing programs to be written.
∂13-Mar-89 1452 X3J13-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 14:52:29 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA07899; Mon, 13 Mar 89 15:50:10 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02499; Mon, 13 Mar 89 15:50:07 -0700
Date: Mon, 13 Mar 89 15:50:07 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132250.AA02499@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
Forum: Compiler
Issue: COMPILE-ENVIRONMENT-CONSISTENCY
References: CLtL p. 68-69, 143, 321
RAM's "Compiler Cleanup Proposal #3"
Category: CLARIFICATION
Edit History: V1, 2 Sep 1988, Sandra Loosemore (initial draft)
V2, 9 Sep 1988, Sandra Loosemore (incorporate suggestions)
V3, 26 Oct 1988, Sandra Loosemore (add suggestion from Benson)
V4, 08 Mar 1989, Sandra Loosemore (wording changes)
Problem Description:
CLtL does not clearly specify what aspects of the compiletime
environment the compiler (or other preprocessor) may "wire in" to code
being compiled. At what time (compiletime or runtime) are certain
kinds of definitions "captured"? What happens if these definitions
are not consistent at both compile and run times?
Proposal COMPILE-ENVIRONMENT-CONSISTENCY:CLARIFY:
The process of compilation causes certain kinds of information present
in the compiletime environment to be captured and incorporated into
the resulting compiled code. Other kinds of information may not be
captured until the compiled code is actually run.
Specifically:
(1) The following information *must* be present in the compiletime
environment for the program to be compiled correctly. This
information need not also be present in the runtime environment.
(a) In conforming code, macros referenced in the code being compiled
must have been previously defined in the compiletime environment.
The compiler must treat any form that is a list beginning with
a symbol that does not name a macro or special form as a function
call. (This implies that SETF methods must also be available at
compiletime.)
(b) In conforming code, variables that are intended to be bound
specially must be declared SPECIAL in the compiletime environment
before any bindings of that variable are processed by the compiler.
The compiler must treat any binding of an undeclared variable as a
lexical binding.
(2) The compiler *may* incorporate the following kinds of information
into the code it produces, if the information is present in the
compiletime environment and is referenced within the code being
compiled. Except where some other behavior is explicitly stated, when
the compiletime and runtime definitions are different, it is
unspecified which will prevail within the compiled code. In all
cases, the absence of the information at compiletime is not an error,
but its presence may enable the compiler to generate more efficient
code.
(a) The compiler may assume that functions that are defined and
declared INLINE in the compiletime environment will retain the
same definitions at runtime.
(b) The compiler may assume that, within a named function, a
recursive call to a function of the same name refers to the
same function, unless that function has been declared NOTINLINE.
(c) COMPILE-FILE may assume that, in the absence of NOTINLINE
declarations, a call within the file being compiled to a named
function which is defined in that file refers to that function.
(This permits "block compilation" of files.) The behavior of
the program is unspecified if functions are redefined individually
at runtime.
(d) The compiler may assume that the signature (or "contract") of
all built-in Common Lisp functions will not change. In addition,
the compiler may treat all built-in Common Lisp functions as if
they had been proclaimed INLINE.
(e) The compiler may assume that the signature (or "contract") of
functions with FTYPE information available will not change. (See
issue FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS.)
(f) The compiler may "wire in" the values of symbolic constants
that have been defined with DEFCONSTANT in the compiletime
environment.
(g) The compiler can assume that type definitions made with DEFTYPE
or DEFSTRUCT in the compiletime environment will retain the same
definition in the runtime environment. It may also assume that
a class defined by DEFCLASS in the compiletime environment will
be defined in the runtime environment in such a way as to have
the same superclasses and metaclass. This implies that
subtype/supertype relationships of type specifiers will not
change between compiletime and runtime. (Note that it is not
an error for an unknown type to appear in a declaration at
compiletime, although it is reasonable for the compiler to
emit a warning in such a case.)
(h) The compiler may assume that if type declarations are present
in the compiletime environment, the corresponding variables and
functions present in the runtime environment will actually be of
those types; otherwise, the runtime behavior of the program is
undefined.
(3) The compiler *must not* make any additional assumptions about
consistency between the compiletime and runtime environments. In
particular:
(a) The compiler may not assume that functions that are defined
in the compiletime environment will retain the either the
same definition or the same signature at runtime, except
in situations (2a) through (2e) above. It is, however,
permissible for the compiler to emit warning messages when
compiling calls to functions that are defined in the compiletime
environment, but where the wrong number or type of arguments
are supplied.
(b) The compiler may not signal an error if it sees a call to a
function that is not defined at compiletime, since that function
may be provided at runtime. Again, it is permissible for the
compiler to emit a warning in these situations.
Rationale:
This proposal generally reflects current practice.
Current Practice:
There don't seem to be any compilers around that do not implement the
provisions of item (1).
For item (2), most compilers (including Lucid) optimize self-recursive
calls by default. Most compilers also opencode data structure
accessors (such as CAR) at some level of optimization, and some code
much more complicated built-in functions inline as well. VaxLisp, for
example, normally compiles MEMBER inline. The Lucid compiler makes
use of type declarations to perform generic-to-specific
transformations on many arithmetic and sequence functions, which is
also a form of inlining. KCL performs block compilation by default,
and Lucid does so under certain conditions.
Cost to implementors:
Unknown, but probably minor.
Cost to users:
Since most implementations appear to be largely in conformance with the
proposal, users should notice little difference.
Benefits:
The presence of a definite specification of what may happen when will
help users structure their programs so they will compile correctly in
all Common Lisp implementations.
Discussion:
Most of the discussion on this issue has been centered on the
terminology describing error situations for item (2). In most cases
where there is an inconsistency between compile-time and run-time, the
results will be unpredictable but harmless. The major exception is
violation of type declarations, which is a "crash-and-burn" error in
many implementations.
There has also been some concern raised that item (3) would prohibit
such things as a cross-compiler that produces standalone programs in
an environment that disallows redefinition of functions. The intent
of this proposal is not to prohibit a compiler from having a magic
switch that imposes additional restrictions on the programs it
compiles, but such a compiler would not be a compiler for Common Lisp.
Several people have expressed reservations about items 2b and 2c, saying
that self-tail-recursion optimization and block compilation should not
be the default behavior of the compiler. Gail Zacharias responds:
This item [2c] has nothing to do with whether anybody does it by
default. The question is whether an end user can take a Common Lisp
program whose internals he's not familiar with, block-compile it, and
be guaranteed that it will continue to function correctly. This item
says that yes, a correct CL program must explicitly indicate what
functions in the source it will redefine at runtime. I don't think
this places such a great burden on the programmer. Without this
provision, only somebody intimately familiar with a program could know
whether it can be safely block-compiled, making block-compilation
useless in the context of portable CL programs.
This thing about "block compilation shouldn't be the default" seems to
come up every time this item is discussed. That's an environment
question and is not addressed by the proposal. The proposal simply
says that block compilation should be legal.
∂13-Mar-89 1514 X3J13-mailer issue COMPILE-FILE-SYMBOL-HANDLING, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 15:14:36 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA08718; Mon, 13 Mar 89 16:12:23 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02542; Mon, 13 Mar 89 16:12:19 -0700
Date: Mon, 13 Mar 89 16:12:19 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132312.AA02542@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILE-FILE-SYMBOL-HANDLING, version 2
Forum: Compiler
Issue: COMPILE-FILE-SYMBOL-HANDLING
References: CLtL p. 182
Issue IN-PACKAGE-FUNCTIONALITY
Issue CONSTANT-COMPILABLE-TYPES
Issue DEFPACKAGE (passed)
Category: CHANGE/CLARIFICATION
Edit History: V1, 01 Feb 1989, Sandra Loosemore
V2, 12 Mar 1989, Sandra Loosemore (discussion, error terms)
Status: Ready for release
Problem Description:
It is not clear how COMPILE-FILE is supposed to specify to LOAD how
symbols in the compiled file should be interned. In particular, what
happens if the value of *PACKAGE* is different at load-time than it
was at compile-time, or if any of the packages referenced in the file
are defined differently?
There are three proposals: CURRENT-PACKAGE, HOME-PACKAGE, and
REQUIRE-CONSISTENCY.
Proposal COMPILE-FILE-SYMBOL-HANDLING:CURRENT-PACKAGE:
When a compiled file is loaded, the interned symbols it references
are found by the following procedure. The rules are applied in the
order listed and only the first applicable rule has any effect.
(1) Any symbol accessible at compile time in the package that is the
value of *PACKAGE* is found by calling INTERN at load time with one
argument, the name of the symbol.
(2) A keyword symbol is found by finding or creating a keyword symbol
with the same name.
(3) A symbol that at compile time is an external symbol of its home
package is found at load time by finding the package with the same
name as the compile-time home package, and then finding an exported
symbol of that package with the same name as the compile-time symbol.
If no such package exists, no such symbol exists, or the symbol is not
exported, an error is signalled.
(4) Any other symbol is found by calling INTERN at load time with two
arguments, the name of the symbol and the package with the same name
as the compile-time symbol's home package. If no such package exists,
an error is signalled.
The goal of this procedure is for each symbol reference to be
resolved to the same symbol when a compiled file is loaded as when
the source file is loaded directly with LOAD. It is possible to
create package structures that make that impossible; for example, it
is possible for a symbol to be inaccessible from its own home
package. A conforming program cannot depend on any symbol
resolution behavior that is not provided by the above four rules.
If any top level form in a compiled file changes the value of
*PACKAGE*, other than a SELECT-PACKAGE appearing as the first
top level form in the file, the package in which the loader will
place the constant symbols referenced in the file is unspecified.
Rationale:
Proposal CURRENT-PACKAGE makes COMPILE-FILE/LOAD follow the same
rules as PRINT/READ. For any symbol not written with a package
prefix in the source file (which should be the great majority of
them), CURRENT-PACKAGE will make loading the compiled file get the
same symbols as loading the source file.
The reason for the rule about changing the value of *PACKAGE* is that
many loaders cache the interning of symbols; if the same symbol
appears multiple times in the source file, its name may only be
looked up once at load time. Since not all loaders are required to
work this way, changing *PACKAGE* in mid-file is not allowed,
because the effect on later occurrrences of a symbol would be
implementation-dependent.
Proposal COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE:
When a compiled file is loaded, the interned symbols it references are
found by calling INTERN at load time with two arguments, the name of
the symbol and the package with the same name as the compile-time
symbol's home package. If no such package exists, an error is
signalled.
The goal of this procedure is for each symbol reference to be resolved
to the same symbol when a compiled file is loaded as when the source
file was processed by COMPILE-FILE. A conforming program cannot
depend on any symbol resolution behavior that is not provided by the
above rule.
If any top level form in a compiled file changes the value of
*PACKAGE* when the file is loaded interpretively but not during
compile-time processing by COMPILE-FILE, the package in which the
loader will place the constant symbols referenced in the file is
unspecified.
Rationale:
The behavior specified in this proposal is simple and easy to
understand (there is only one rule to remember instead of four).
It does not require any restrictions on where top-level
SELECT-PACKAGE forms may appear in the file. It allows a compiled
file that does not include an explicit SELECT-PACKAGE to be loaded
successfully no matter what the load-time value of *PACKAGE* is,
as long as the compile-time value of *PACKAGE* was the "right"
package.
Proposal COMPILE-FILE-SYMBOL-HANDLING:REQUIRE-CONSISTENCY:
In order to guarantee that compiled files can be loaded correctly,
users must ensure that the packages referenced in the file are defined
consistently at compile and load time. Conforming Common Lisp programs
must satisfy the following requirements:
(1) The value of *PACKAGE* when the contents of the file are compiled
by COMPILE-FILE must be the same as the value of *PACKAGE* when
the file is loaded. In particular:
(a) If any top level form in a compiled file changes the value
of *PACKAGE*, other than a SELECT-PACKAGE appearing as the first
top-level form in the file, the package in which the loader
will place the constant symbols referenced in the file is
unspecified.
(b) If the first top-level form in the file is not a call to
SELECT-PACKAGE, then the value of *PACKAGE* at the time LOAD is
called must be a package with the same name as the package that
was the value of *PACKAGE* at the time COMPILE-FILE was called.
(2) For all symbols that were accessible in *PACKAGE* at compile
time but whose home package was another package, at load time there
must be a symbol with the same name that is accessible in both the
load-time *PACKAGE* and in the package with the same name as the
compile-time home package.
(3) For all symbols in the compiled file that were external symbols in
their home package at compile time, there must be a symbol with the
same name that is an external symbol in the package with the same name
at load time.
If any of these conditions do not hold, the package in which LOAD looks
for the affected symbols is unspecified. Implementations are permitted
to signal an error or otherwise define this behavior.
Otherwise, when a compiled file is loaded, the interned symbols it
references are found by calling INTERN at load time with two
arguments, the name of the symbol and the package with the same name
as the compile-time symbol's home package. If no such package exists,
an error is signalled.
Rationale:
Any program that behaves differently under the other two proposals
is already nonportable. This proposal is merely an explicit
statement of the status quo, namely that users cannot depend on
any particular behavior if the package environment at load time is
inconsistent with what existed at compile time.
Current Practice:
PSL/PCLS implements something very similar to proposal HOME-PACKAGE,
as does A-Lisp. Utah Common Lisp implements something like proposal
CURRENT-PACKAGE, but the chief compiler hacker says he thinks that
proposal HOME-PACKAGE actually makes more sense, and agrees that any
program that behaves differently under the two proposals is broken.
The TI Explorer currently implements proposal HOME-PACKAGE, after
trying it both ways.
KCL implements something like HOME-PACKAGE (symbols in the compiled
file are explicitly qualified with the name of their home package),
except that it differentiates between internal and external symbols.
Lucid Lisp appears to implement something like proposal CURRENT-PACKAGE.
Symbolics Genera implements CURRENT-PACKAGE. Symbolics Cloe probably
does also.
Coral also implements something like proposal CURRENT-PACKAGE.
Cost to implementors:
Proposals HOME-PACKAGE and CURRENT-PACKAGE would be incompatible
changes for implementations that currently do things the other way.
It would probably be easier to convert to HOME-PACKAGE than
CURRENT-PACKAGE, since it is less complicated.
Proposal REQUIRE-CONSISTENCY is intended to be compatible with either
of the other two proposals, but it may not be entirely compatible with
the details of current implementations.
Cost to users:
Proposal HOME-PACKAGE places the fewest restrictions on user programs.
Proposal CURRENT-PACKAGE places a restriction on where and how the value
of *PACKAGE* may be changed within the file.
Proposal REQUIRE-CONSISTENCY places even more restrictions on user
programs.
Most of these restrictions are probably already necessary in portable
programs. However, some nonportable programs that depend on the "other"
model may be broken by proposals HOME-PACKAGE or CURRENT-PACKAGE.
For a discussion of how these proposals treat nonportable or erroneous
programs, see the "Analysis" section below.
Benefits:
COMPILE-FILE's treatment of symbols is made explicit in the standard.
Analysis:
Proposals CURRENT-PACKAGE and HOME-PACKAGE present two different
models of how this problem might be solved. Essentially, proposal
CURRENT-PACKAGE uses the same rules as PRINT/READ in deciding when to
qualify symbols with a package name and where to find unqualified
symbols. Proposal HOME-PACKAGE requires -all- symbols written to the
compiled file to be qualified with an explicit package, and the loader
simply INTERNs the symbol names in that package.
These two proposals differ in the following situations. Proposal
REQUIRE-CONSISTENCY, in effect, says that valid programs do not cause
any of these situations to occur, and the behavior in such cases is
unspecified (allowing both models to be used as valid implementation
techniques).
(1) The situation where the file does not contain a SELECT-PACKAGE
and where the compile-time value of *PACKAGE* is a package with a
different name than the load-time value of *PACKAGE*.
Proposal CURRENT-PACKAGE would intern the names of symbols that
were accessible in *PACKAGE* at compile time in *PACKAGE* at load time.
Proposal HOME-PACKAGE would intern the names of symbols that
were accessible in *PACKAGE* at compile time in the package with
the same name as their compile-time home package.
In general, programs must be compiled in the "right" package, so
that the compiler can find and apply the correct macro expansions,
type definitions, and so on; see issue COMPILE-ENVIRONMENT-CONSISTENCY.
As a result of macroexpansion or other transformations applied by
the compiler, the compiled file may contain symbol references that
were not present in the source file. Proposal CURRENT-PACKAGE may
cause problems because these references may be resolved to be
symbols other than the ones that were intended. Since proposal
HOME-PACKAGE remembers the home package of all symbols, it is much
more likely to find the correct symbols at load time.
(2) The situation where *PACKAGE* is altered by a top-level form
that is not a SELECT-PACKAGE which is the first top-level form in
the file.
Proposal CURRENT-PACKAGE says this is illegal. This is because
of the difficulty in deciding what the "current package" is, if it
is allowed to change throughout the file.
Proposal HOME-PACKAGE says this is OK, as long as *PACKAGE* is
altered in the same way at compile time as when the file is loaded
interpretively. This is possible because the behavior this
proposal specifies does not depend on what the value of *PACKAGE*
is once symbols in the source file have been read by COMPILE-FILE.
Some people argue that allowing *PACKAGE* to be switched in
mid-file is a bad idea anyway; it is not really necessary and it
implies a restriction on COMPILE-FILE to read forms from the file
one at a time, processing each form before the next call to READ.
Others argue that restricting SELECT-PACKAGE to be the first
top-level form is an artificial contrivance. The compile-time
behavior of SELECT-PACKAGE is well-defined no matter where it
appears in the file. There is also a problem defining what "the
first top-level form" really means. Finally, this model requires
all package definitions to be made externally to the file, which
may be inconvenient for smaller programs that now contain the
package definition and package contents all in one file.
(3) The situation where there is a symbol accessible in the
compile-time value of *PACKAGE* but with another home package, and
where at load time there is not a symbol with the same name that
is accessible in both packages. This situation might occur, for
example, if at compile time there is a symbol that is external in
its home package and that package is used by *PACKAGE*, but where
there is no such external symbol in that package at load time, or
the load-time *PACKAGE* does not use the other package.
Proposal CURRENT-PACKAGE would find or create a symbol accessible
in *PACKAGE*.
Proposal HOME-PACKAGE would find or create a symbol accessible in
a package with the same name as the symbol's compile-time home
package.
Some people feel that the behavior of proposal CURRENT-PACKAGE is
more intuitive in this situation, and that it is more forgiving of
differences between the compile-time and load-time package
structures. Others feel that the behavior of HOME-PACKAGE is more
intuitive, and that if there have been significant changes to the
package structures, it is probably an indication that the file
needs to be recompiled anyway, since the compiler might have
picked up macro definitions and the like from the wrong package.
(4) The situation where a symbol is external in its home package
and where there is no such external symbol in that package at load
time.
Proposal CURRENT-PACKAGE would quietly find or create the symbol
in *PACKAGE* if the symbol were accessible in *PACKAGE* at compile
time. Otherwise, it will signal an error.
Proposal HOME-PACKAGE would always just quietly find or create the
symbol as internal in its home package.
Not complaining when a symbol that is supposed to be external
isn't can be seen as a violation of modularity. However, it seems
like this argument should apply equally to symbols whose home
package is *PACKAGE* as symbols whose home package is somewhere
else.
Discussion:
Loosemore is opposed to proposal CURRENT-PACKAGE, but would be
less opposed to it if it contained an explicit statement that
*PACKAGE* must be a package with the same name at load time as at
compile time. She thinks proposal HOME-PACKAGE is the best of the
options presented here.
Moon is opposed to proposal HOME-PACKAGE, but would be less
opposed to it if it required an error to be signalled when a
symbol that was external at compile time is not external at load
time. He thinks proposal CURRENT-PACKAGE is the best of the options
presented here.
John Kolts, who did the implementation on the TI Explorer, recalls:
My primary motivation was compile/load consistency. I thought it was
important that during loading all symbol references should resolve to
the same symbol as they would have during the compilation. If, for
instance, the packages used by *package* were different at compile
time than at load time, my approach would still intern the accessible
symbols in the "right" package during loading. [...] Of course, such
an approach means that loading the [compiled file] could give results
incompatible with loading the LISP file directly, but I felt that if
behavior consistent with some altered package structure was desired,
the file should be recompiled, a relatively small price to pay for the
benefit of this consistency.
A related consideration was that remembering the home package seemed to
be important for proper macro expansion in certain cases.
What was apparent was that there were several defensible approaches,
none of which was obviously the absolutely right way to handle certain
pathological situations. Making the expected behavior explicit in a
standard is a good idea.
David Gray says:
There really shouldn't be anything wrong about using SELECT-PACKAGE
multiple times within a file as long as it is used at top level so
that the compiler knows that the current package is being changed.
Cris Perdue says:
[Proposal HOME-PACKAGE] doesn't ensure that the home package remains
the same across compilation and loading, which I consider the key
consideration. How about this statement instead?
"When a file is compiled, the symbol name is recorded together
with the home package name and an indication of whether the
symbol is external in its home package. At load time the
symbol is effectively looked up with:
(find-symbol string (find-package pkg-name))
If the symbol is noted as external, it must be found at load
time as :external. If it is noted as internal, it must either
be present in the package or not found at all. If it is not found
at all, it is created as if by:
(intern string (find-package pkg-name))
If the package system is not in a suitable state, an error is
signalled."
This is what I consider "the right thing".
JonL White says:
I don't believe we have anything to gain at this point in trying to
standardize the faslout package-qualification algorithm; this is
notwithstanding that standardizing PRINT output, as an interchange
format, is an absolute requirement [even though READ-of-PRINT will
likely be even more information losing than loading in a compiled
file!]
∂13-Mar-89 1517 X3J13-mailer issue COMPILER-LET-CONFUSION, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 15:16:50 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA08737; Mon, 13 Mar 89 16:14:30 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02546; Mon, 13 Mar 89 16:14:26 -0700
Date: Mon, 13 Mar 89 16:14:26 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132314.AA02546@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILER-LET-CONFUSION, version 7
Issue: COMPILER-LET-CONFUSION
Forum: Compiler
References: CLtL p. 112
Category: CHANGE
Edit History: V1, 27 Sep 1988, Sandra Loosemore (initial version)
V2, 04 Oct 1988, Sandra Loosemore (add another example)
V3, 31 Oct 1988, Sandra Loosemore (only proposal ELIMINATE)
V4, 08 Jan 1989, Kent M. Pitman (new alternative)
V5, 09 Jan 1989, Sandra Loosemore (discussion)
V6, 08 Mar 1989, Sandra Loosemore (general updating)
V7, 13 Mar 1989, Sandra Loosemore (fix bug from V6)
Problem Description:
The description of the COMPILER-LET special form in CLtL is confusing
to many people. There are no examples provided to make it clear how it
is supposed to be used. The only description which is offered is overly
concrete, which has led to confusion about the intent of COMPILER-LET,
and about its implementability.
The intent of COMPILER-LET was to permit information to be communicated
between macros by use of dynamic variables at macroexpansion time.
It was not necessary to the intended uses of COMPILER-LET that such
variables ever be bound at execution time.
Unfortunately, probably because some implementations did not primitively
support COMPILER-LET at the time CLtL was written, an exception was
permitted to make COMPILER-LET `more or less work' in interpreters:
the COMPILER-LET variables were permitted to be bound at execution time.
The problem was further compounded by the fact that CLtL presented this
exception as part of COMPILER-LET's contract rather than as an
implementation note, and by the fact that no examples of actually using
COMPILER-LET correctly are provided.
One particular case where problems have resulted is a situation like
(compiler-let ((*v* 1))
#'(lambda () (m)))
where M is a macro that refers to *V*. In some implementations, M is
not macroexpanded until the dynamic extent of the *V* binding has
ended.
Subtle bugs can be introduced because of the different handling of the
variable bindings in the interpreter and the compiler. In compiled
code, the bindings are only lexically visible during the expansion of
macros at compile time, while in interpreted code the bindings have
dynamic scope and may also be seen during ordinary evaluation if
evaluation and macroexpansion happen "in parallel".
Further compatibility problems can result from the value forms being
evaluated in a null lexical environment in the compiler and the ordinary
lexical environment in the interpreter.
Background and Analysis:
It should be clear up front that COMPILER-LET is not computationally
essential. Most (if not all) uses of it can be rewritten using MACROLET
or SYMBOL-MACROLET.
A typical use of COMPILER-LET might be:
(defvar *local-type-declarations* '())
(defmacro local-type-declare (declarations &body forms)
`(compiler-let ((*local-type-declarations*
(append ',declarations *local-type-declarations*)))
,@forms))
(defmacro typed-var (var)
(let ((type (assoc var *local-type-declarations*)))
(if type `(the ,(cadr type) ,var) var)))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
The same thing could be accomplished using MACROLET:
(defmacro local-type-declare (declarations &body forms)
(local-type-declare-aux declarations forms))
(defmacro typed-var (var) var)
(eval-when (eval compile load)
(defun local-type-declare-aux (declarations forms)
`(macrolet ((typed-var (var)
(let ((type (assoc var ',declarations)))
(if type `(the ,(cadr type) ,var) var)))
(local-type-declare (new-declarations &body new-forms)
(local-type-declare-aux
(append new-declarations ',declarations)
new-forms)))
,@forms)))
A further alternative would be to use SYMBOL-MACROLET (this particular
implementation assumes that issue DEFINING-MACROS-NON-TOP-LEVEL passes):
(let ((temp (gensym)))
(defmacro local-type-declare (declarations &body forms &environment env)
`(symbol-macrolet ((,temp ',(append declarations
(symbol-macro-value temp env))))
,@forms))
(defmacro typed-var (var &environment env)
(let ((type (assoc var (symbol-macro-value temp env))))
(if type `(the ,(cadr type) ,var) var)))
)
(defun symbol-macro-value (symbol env &optional default)
(multiple-value-bind (expansion macro-p) (macroexpand symbol env)
(if macro-p (eval expansion) default)))
Opinion is divided as to which is more understandable. Some
people find the COMPILER-LET idiom more understandable (assuming that
it can be made to work consistently in compiled and interpreted
code), while others find it just as natural to use MACROLET or
SYMBOL-MACROLET.
The issues are these:
- Is it possible to implement COMPILER-LET in a usefully consistent
way in all implementations?
- Are the benefits of providing a useful and compatible implementation
of COMPILER-LET worth any associated cost?
Two proposals are presented below:
- Option REPAIR argues that COMPILER-LET provides interesting
functionality that can be implemented in a manner that is usefully
consistent across implementations, and that the associated cost
is low enough for it to be worthwhile to do so.
- Option ELIMINATE argues that COMPILER-LET complicates the language
and that providing this construct is not worth the associated
implementation cost.
Proposal (COMPILER-LET-CONFUSION:REPAIR):
Strike the existing definition of COMPILER-LET. Redefine it as follows:
COMPILER-LET [Special form]
COMPILER-LET is similar to LET, but it always makes special
bindings and makes those bindings visible only during
macroexpansion of forms in the body, not during the runtime
execution of those forms.
The intent is that some macros might macroexpand into calls to
COMPILER-LET in which the body would the contain references to
macros which access the variables in the COMPILER-LET.
The initial value forms of the bindings, if any, are always
evaluated in a null lexical context, regardless of whether the
COMPILER-LET expression is being interpreted or compiled.
The initial value forms of the bindings, if any, are evaluated in
a dynamic context where the bindings of any lexically enclosing
COMPILER-LET are visible, and where dynamic execution-time
environment may or may not be visible.
Implementation Note: Permitting the execution-time dynamic
environment to be visible when initializing COMPILER-LET variables
is a concession to some interpreters which may have to do this in
order to keep the cost down. Where feasible, implementors should
try not to make the runtime environment visible.
Rationale:
This gives a consistent description of COMPILER-LET which separates
issues of intent from those of implementation in a way that makes it
possible for portable code to make serious use of it, and which does
not force gratuitous incompatibilities between interpreters and
compilers.
This description of COMPILER-LET can be implemented without undue
cost by all implementations. See "Cost to Implementors" for details.
Cost to Implementors:
Modest, but nontrivial in some implementations.
In compiled code, and in interpreters doing a one-time semantic
prepass, it should be fairly easy for COMPILER-LET to cause the
variables to get bound (using PROGV) during semantic analysis.
In interpreters which do not do a semantic-prepass, it is necessary
to fully macroexpand the body. Assuming the presence of a
SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
could look like:
(DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
(SETQ BINDINGS ;; Assure no non-atom bindings
(MAPCAR #'(LAMBDA (BINDING)
(IF (ATOM BINDING) (LIST BINDING) BINDING))
BINDINGS))
(PROGV (MAPCAR #'CAR BINDINGS)
(MAPCAR #'CDR BINDINGS)
(SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))
This reduces the problem of writing a program capable of doing a
full macroexpansion. Many systems already have such a facility.
Pitman wrote such a facility in Cloe Runtime in order support
SYMBOL-MACROLET (before it was christened a special form); it was
about 750 lines of relatively straightforward, well-commented code.
Cost to Users:
Code currently depending on this feature is either non-existent or
already not portable (due to wide variation in implementation
strategy for COMPILER-LET).
Most users will probably be happy for any interpretation which offers
them a future shot at portability.
Some users have indicated they dislike interpreters which do a semantic
prepass, because they like to be able to dynamically redefine macros
while debugging.
Proposal (COMPILER-LET-CONFUSION:ELIMINATE):
Remove COMPILER-LET from the language.
Rationale:
Some people think that having one less special form would simplify the
language. The revised COMPILER-LET semantics, which require
COMPILER-LET to make special bindings which are only visible during
expansion of macros which appear lexically within its body, are
not shared by any other feature in the language, and require a
fairly complex implementation technique. There are other
constructs which are strictly lexical that can be readily used
to solve the same kinds of problems that COMPILER-LET is intended to
be used for.
Cost to Implementors:
Minimal. Implementations could continue to support COMPILER-LET as
an extension.
Cost to Users:
Code currently depending on this feature is either non-existent or
already not portable (due to wide variation in implementation
strategy for COMPILER-LET).
People who use COMPILER-LET would have to rewrite their programs to use
some other construct. As discussed above, most uses of COMPILER-LET
for communication between macros can be handled using MACROLET or
SYMBOL-MACROLET, though some perspicuity may be lost in the process.
Current Practice:
Some implementations have implemented the description in CLtL.
Users of those implementations (quite reasonably) can't figure how to
use COMPILER-LET and so don't use it much.
Some implementations (the ones from which COMPILER-LET originally came)
continue to use their pre-CLtL semantics. These semantics are useful, though
incompatible with CLtL (which they largely consider to simply be in error).
Users of those implementations probably use COMPILER-LET somewhat more
often since it has an intelligible behavior, but their code is not portable
since it relies on behaviors which are either contrary to or not guaranteed
by CLtL.
Benefits:
Either way, a potential area of incompatibility between compiled and
interpreted code would be eliminated.
Either way, a potential area of portability trouble would be very
drastically reduced (in the case of the REPAIR option) or eliminated
(in the case of the ELIMINATE option).
Discussion:
Pitman strongly favors COMPILER-LET-CONFUSION:REPAIR. He argues
against the idea of using MACROLET instead of COMPILER-LET, saying:
This is a little misleading because it's like saying you can
do without LET given that you have FLET. You can, but you lose some things
in the process:
Just as rewriting a LET using FLET might slow your computation, so too
a rewrite of COMPILER-LET using MACROLET might slow things down. However,
compilation speed is generally not weighted as heavily as execution speed
by many people, so the loss of speed here may not be as important.
Just as rewriting a LET using FLET might obscure the simplicity of your
intent, so too rewriting COMPILER-LET using MACROLET might obscure your
intent. You'd probably get used to recognizing idioms if you used it often
enough. Certainly this would be true if you didn't have LET. However,
COMPILER-LET is used less often, so not having it would mean that the
code you wrote instead would be much harder to read because people
wouldn't have the necessary familiarity with the idioms involved and so
wouldn't always understand them.
Sandra Loosemore responds:
The argument that using MACROLET is more inefficient than COMPILER-LET
is questionable. Both of the suggested implementation techniques for
COMPILER-LET involve considerable overhead.
If COMPILER-LET were not part of the language, people wouldn't think in
terms of rewriting COMPILER-LETs as MACROLETs; instead, they'd think of
how to use MACROLET in the first place to solve their problems. This
is what people who now use implementations with broken COMPILER-LETs
already do. Since MACROLET is now used much more frequently than
COMPILER-LET, that argues that people are much more familiar with
MACROLET idioms than COMPILER-LET idioms.
Also, note that the intent of the revised COMPILER-LET definition is
to make the binding only lexically visible within the body. Using
special binding for this purpose is troublesome. Both the MACROLET
and SYMBOL-MACROLET solutions are completely lexical and avoid all
the problems associated with special binding.
Glenn Burke thinks it needs to be emphasized that the code-walker
mentioned in the REPAIR proposal does not need to be portable. He
says:
The present wording makes it sound like a piece of cake to do with
portable code, when the reality is that a good fraction of CL cleanup
effort has involved the lack of capability of producing such a beast.
Without one or more of a number of proposals being accepted, a fully
correct portable code walker cannot be built, in my belief.
I object to the flippant attitude of just "presupposing" this
"trivial" function which "we know how to do".
∂13-Mar-89 1531 X3J13-mailer **DRAFT** issue DEFCONSTANT-NOT-WIRED, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 15:30:56 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA09104; Mon, 13 Mar 89 16:28:40 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02557; Mon, 13 Mar 89 16:28:37 -0700
Date: Mon, 13 Mar 89 16:28:37 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132328.AA02557@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue DEFCONSTANT-NOT-WIRED, version 6
We don't expect to ask for a vote on this issue -- the writeup is just
being distributed so that we can refer to it in case the issue ever
comes up again. None of the suggestions listed here seemed to have a
great deal of support among people on the cl-compiler list, and all of
them have problems we haven't been able to resolve yet.
Forum: Compiler
Issue: DEFCONSTANT-NOT-WIRED
References: CLtL pages 68-69
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS,
PROCLAIM-LEXICAL,
DECLARE-TYPE-FREE,
DEFCONSTANT-SPECIAL
Category: ADDITION
Edit history: 09 Oct 1988, V1 by David Gray
27 Oct 1988, V2 by David Gray (new proposal)
10 Nov 1988, V3 by David Gray - updated proposal, rationale
and discussion sections in response to comments.
21 Nov 1988, V4 by David Gray - SPECIAL cancels CONSTANT;
CONSTANT doesn't require previous SPECIAL.
28 Nov 1988, V5 by Sandra Loosemore (clean up, fix
some consistency problems)
13 Mar 1989, V6 by Sandra Loosemore (start over)
Status: **DRAFT**
Problem description:
DEFCONSTANT performs two different functions:
- It says that it is an error to SETQ or rebind the variable which
is being defined as a constant.
- It gives the compiler permission to evaluate the initial value form
at compile time, and to build assumptions about the value into
programs being compiled.
In some cases, one would like to have the first behavior without
getting the second. In particular, one would like to get the same
behavior with regard to signalling errors and warnings that you get
with DEFCONSTANT.
Common Lisp provides no mechanism for specifying a variable should
be treated in this way.
Proposal DEFCONSTANT-NOT-WIRED:FIX-DEFPARAMETER:
This is what DEFPARAMETER was supposed to be used for. The description
of DEFPARAMETER needs to be clarified to reflect this, perhaps by
saying that a continuable error should be signalled if an attempt is
made to SETQ or rebind a variable defined with DEFPARAMETER.
Rationale:
DEFPARAMETER apparently derives from Zetalisp's DEFCONST construct,
which was used to indicate that values that would "never" change,
without licensing the compiler to make assumptions about that value.
However, most uses of DEFCONST have apparently been changed to use
DEFCONSTANT instead.
Objections:
Some people don't think that DEFPARAMETER was intended to be used
in this way and that this would be an incompatible change.
Proposal DEFCONSTANT-NOT-WIRED:RESTORE-DEFCONST:
Leave DEFPARAMETER alone but add another construct with the semantics
described above.
Rationale:
Some people don't think that DEFPARAMETER was intended to be used
in this way.
Objections:
We haven't been able to come up with a good name for this construct.
"DEFCONST" is too confusing and all of the other names that have
been suggested are too long. Also, having so many macros for
declaring variables with is confusing.
Proposal DEFCONSTANT-NOT-WIRED:NEW-DECLARATION:
Add a new CONSTANT declaration to the language which can be used to
declare that a variable cannot be SETQ'd or bound within the scope of
the declaration.
Rationale:
This solves the problem and also provides more general functionality.
For example, one could declare that a lexical variable won't be
SETQ'ed.
Objections:
We haven't been able to decide whether a CONSTANT declaration should
augment or replace a SPECIAL or LEXICAL declaration. How do you
initialize a variable that has been proclaimed CONSTANT? Some people
have objected to calling the declaration CONSTANT unless it is
equivalent to what a DEFCONSTANT does.
Proposal DEFCONSTANT-NOT-WIRED:ADD-OPTIONAL-ARGUMENT:
Add an optional argument to DEFCONSTANT to indicate whether the
compiler can make assumptions about the constant's value.
Rationale:
It would solve the problem.
Objections:
It would make DEFCONSTANT have different syntax from DEFVAR and
DEFPARAMETER.
Proposal DEFCONSTANT-NOT-WIRED:DEFINE-VARIABLE
Define a single macro, DEFINE-VARIABLE, that can be used to do what
DEFVAR, DEFPARAMETER, and DEFCONSTANT now do, plus the proposed new
functionality, plus possibly handle lexical variables as well
(if proposal PROCLAIM-LEXICAL passes). Arguments to the macro
could be used to control whether the value is allowed to change
and whether the compiler is allowed to make assumptions about the
value.
Rationale:
It would solve the problem without cluttering up the language with
new defining macros for every possible combination of behavior.
Objections:
Nobody has proposed anything definite yet.
Discussion:
This issue was discussed at length on the cl-compiler mailing list
last fall, without coming up with an acceptable proposal. It didn't
appear that any of the alternatives had a great deal of support. This
writeup summarizes the alternatives that have been proposed at various
times. Some of them (particularly NEW-DECLARATION) have been
considered in detail, and others (DEFINE-VARIABLE) haven't been
pursued at all.
∂13-Mar-89 1533 X3J13-mailer issue DEFINE-OPTIMIZER, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 15:33:36 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA09197; Mon, 13 Mar 89 16:31:22 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02562; Mon, 13 Mar 89 16:31:17 -0700
Date: Mon, 13 Mar 89 16:31:17 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132331.AA02562@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue DEFINE-OPTIMIZER, version 5
Forum: Compiler
Issue: DEFINE-OPTIMIZER
References: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Category: ADDITION
Edit history: 28-Sep-88, Version 1 by Pitman
10-Mar-89, Version 2 by Pitman (clarifications, new example),
10-Mar-89, Version 3 by Pitman & Loosemore
11-Mar-89, Version 4 by Pitman
13-Mar-89, Version 5 by Loosemore (discussion)
Status: Ready for release
Problem Description:
Often a general functional interface could be bypassed given explicit
knowledge of the arguments passed. This may happen when the arguments
are constant (or otherwise inferrable), an argument type is known (eg,
due to use of THE or DECLARE), or when some particular pattern of
optional, rest or keyword arguments is apparent.
Most implementations provide internally for optimization of generalized
function call interfaces to more specialized ones, but such an
optimization facility is not provided to Common Lisp users.
The absence of this facility in a portable fashion means that some
CL programs run slower than they need to in some implementations, or
else that some operators that should be implemented as functions end
up getting implemented as macros to assure needed efficiency.
Proposal (DEFINE-OPTIMIZER:NEW-FACILITY):
Introduce a facility for declaring compiler optimizations.
DEFINE-OPTIMIZER name arglist {declaration}* {form}* [Macro]
Defines a compiler optimizer for a function named NAME. The ARGLIST,
DECLARATIONS, and FORMS are treated exactly like the arglist,
declarations, and forms in a DEFMACRO. (The arglist may include
&ENVIRONMENT and &WHOLE.)
The argument NAME must name a function which has been previously
defined. The effects of defining an optimizer for a locally or
globally defined macro, a locally defined function, or a special
form are undefined.
When the optimizer is invoked, the forms are executed in the context
of bindings specified by the arglist, and two values are yielded,
RESULT and VALID-P. (If either of the first or second return value
is non-NIL, then the first return value is considered valid).
If the result is valid, it is a form which is preferable to evaluate
instead of the indicated call.
If a call to DEFINE-OPTIMIZER appears at top-level in a file
being processed by the file compiler, it also makes the optimizer
known at compile-time (similar to the way DEFMACRO makes a macro
definition known to the compiler).
OPTIMIZE-EXPRESSION-1 form env [Function]
Similar to MACROEXPAND-1. Invokes the optimizers for the top level of
FORM, but does not iterate on the result. Returns two values:
RESULT and CHANGED-P.
Note: If an optimizer returns a result which is not valid,
OPTIMIZE-EXPRESSION-1 hides the fact by returning FORM,NIL
rather than NIL,NIL.
OPTIMIZE-EXPRESSION form env [Function]
Iterates calling OPTIMIZE-EXPRESSION-1 until the CHANGED-P result
is NIL.
An implementation must save optimizer definitions created by
DEFINE-OPTIMIZER in case OPTIMIZE-EXPRESSION is attempted, but is
not actually required to call OPTIMIZE-EXPRESSION itself. Interpreters,
for example, may choose to just call the unoptimized form.
Using FLET and MACROLET shadow not only functions and their SETF methods,
but also their optimizers. No portable facility is provided for creating
locally defined optimizers.
The effect of defining optimizations for functions in the LISP package
is not defined. (In some implementations, this would clobber or conflict
with existing advice that may be of higher quality.)
The editor is advised that a non-binding style note such as the
following would also be appropriate:
In general, it is poor style for a programmer to define optimizers for
functions that he does not maintain. This is because the correct
implementation of an optimizer for a function usually depends on an
understanding of the internals of that function. As such, a function
definition and any optimizers should be maintained as a unit so that
they can changes in either can be synchronized as appropriate with the
other.
The effect of using DEFINE-OPTIMIZER on a function declared to be
INLINE is ``unspecified but harmless'' (per new Error Terminology).
That is, since both operations (optimization and inlining) are intended
to be semantics-preserving, no functional difference should be observed.
However, in some implementations the presence of an optimizer may thwart
the ability to inline, or vice versa. Writers of portable code are
encouraged to use either DEFINE-OPTIMIZER or (PROCLAIM '(INLINE ...))
but not both.
Example:
;; These examples are taken literally from the Macsyma sources,
;; modified only to change DEFOPT to DEFINE-OPTIMIZER. The comments
;; were specially written for the X3J13 audience.
;; M+ is adds a Macsyma expression to another Macsyma expression.
;; The Macsyma internal representation for the sum of X and Y is
;; ((MPLUS) X Y). A all the real work is done by SIMPLIFY, which
;; reduces the expression as needed necessary. However, SIMPLIFY
;; is very complicated, and considerable speed can be gained by
;; entering it at specific known places.
(DEFUN M+ (&REST TERMS)
(PROTECT-&REST-VARIABLE TERMS)
(SIMPLIFY `((MPLUS) ,@TERMS)))
(DEFINE-OPTIMIZER M+ (&REST TERMS)
(COND ((= (LENGTH TERMS) 2) `(ADD2* ,@TERMS))
(T `(ADDN (LIST ,@TERMS) NIL))))
;; M- negates a Macsyma expression, or substracts two Macsyma
;; expressions. Once you figure out which of the two operations is
;; to be done, the problem is similar to that of M+ above. However,
;; often the decision can be made at compile time. In this case,
;; INLINE functions would have worked ok, except that not all
;; implementations do inlining, and even those that do may fail to
;; recognize that EXP2 being NIL means that a test can be eliminated
;; or dead code can be eliminated. Using optimizers is far more
;; likely to be useful in practice.
(DEFUN M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
(M--INTERNAL-NEGATE EXP1)
(M--INTERNAL-SUBTRACT EXP1 EXP2)))
(DEFINE-OPTIMIZER M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
`(M--INTERNAL-NEGATE ,EXP1)
`(M--INTERNAL-SUBTRACT ,EXP1 ,EXP2)))
Rationale:
Many large portable applications expect such a facility on an
implementation-specific basis. Others would use one if available.
Even if implementations don't use the provided optimizers primitively,
user macros and code-walkers can invoke them, so the facility wouldn't
be completely useless even in those implementations.
Current Practice:
Symbolics Genera provides an optimizer facility which is more elaborate
but not fundamentally incompatible with this facility.
Many (if not most) serious implementations provide a similar facility.
For example, Lucid provides "compiler macros" which serve the same
purpose.
Cost to Implementors:
Since the implementation is not required to use this facility, the
cost of providing the proposed support is very small.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Portable code would be slower than necessary in some situations.
Benefits:
Some existing non-portable code could become portable.
Aesthetics:
Providing a separate optimizer definition from a main function definition
makes a possibility that the optimizer and main function could drift out
of synch. However, most places where this gets used in the first place
are places where speed is of paramount importance and the programmer is
willing to invest effort in maintaining things correctly and to accept the
risk of lossage if s/he fails.
This is a fairly clean and simple extension which adds significant
power to the compiler.
Discussion:
Pitman strongly supports this proposal, the design of which is modeled
directly after that which has been used in Macsyma for many years.
Information about argument type can come from two different sources:
THE and declarations (via PROCLAIM or DECLARE). The former information
is portably accessible, the latter is not. While a separate proposal
(SYNTACTIC-ENVIRONMENT-ACCESS) for allowing program access to type
declarations would be make this facility more useful, it is still
quite useful without it, as the examples from Macsyma illustrate.
Some implementations provide a way to provide more than one optimizer
for the same function. A multiple optimizer facility can be written
in terms of this simpler facility and vice versa, so the simpler of
the two facilities is proposed here.
Some people have suggested that they would like to see a pattern
matching facility integrated into this facility. The design of a
facility that would satisfy everyone would take a lot of time and
effort. At this point, there is no chance that the design of such a
facility would occur in time for acceptance into the standard.
The choice is this or nothing. Pitman thinks the language is much
better off with some form of optimization support than none.
Loosemore says:
Although I don't really think this is an essential feature to include
in the standard, I don't have any strong objection to adding it. If
people think it's a good idea to provide a standard interface for this
kind of thing, this is a good proposal for doing it -- it's fairly
simple, doesn't introduce any radically new ideas, and is general
enough to allow alternate interfaces (such as the pattern matcher) to
be layered on top of it.
Barrett says:
I think you may have gotten the sense of Cris' INLINE comment wrong.
I believe what he was suggesting is that NOTINLINE declarations should
inhibit optimizers, a position I agree with. I also think it would be
better to specify the behavior when both an optimizer and an inline
are present, rather than leaving it 'unspecified but harmless'. I'd
suggest that optimizers have precedence. The rational is that this
allows an optimizer to look for special patterns in the arguments, and
to defer to the inline if it doesn't find them. Of course, there's
the problem that the compiler might then ignore the inline.
∂13-Mar-89 1536 X3J13-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 15:36:01 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA09314; Mon, 13 Mar 89 16:33:46 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02565; Mon, 13 Mar 89 16:33:44 -0700
Date: Mon, 13 Mar 89 16:33:44 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132333.AA02565@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 8
Forum: Compiler
Issue: DEFINING-MACROS-NON-TOP-LEVEL
References: CLtL p. 66-70, 143
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue COMPILER-LET-CONFUSION
Category: CLARIFICATION, ENHANCEMENT
Edit History: 6-May-88, V1 by Sandra Loosemore
9-Jun-88, V2 by Sandra Loosemore
12-Sep-88, V3 by Sandra Loosemore (fix garbled section 4)
21-Sep-88, V4 by Sandra Loosemore (clarify section 5)
16-Dec-88, V5 by Sandra Loosemore (major restructuring)
31-Dec-88, V6 by Sandra Loosemore (wording clarifications)
07-Jan-89, V7 by Sandra Loosemore (add example)
09-Mar-89, V8 by Sandra Loosemore (more restructuring)
Status: Ready for release
Problem Description:
CLtL leaves the interpretation of defining forms such as DEFMACRO and
DEFVAR that appear in other than top-level locations unclear.
On page 66, it is stated: "It is not illegal to use these forms at
other than top level, but whether it is meaningful to do so depends on
context. Compilers, for example, may not recognize these forms
properly in other than top-level contexts". At least one implementation
has interpreted this to mean that it is permissible to simply refuse
to compile defining macros that do not appear at top-level.
Proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW:
(1) Remove the language from p. 66 of CLtL quoted above. Clarify that
while defining macros normally appear at top level, it is meaningful
to place them in non-top-level contexts and that the compiler must
handle them properly in all situations. However, the compile-time side
effects described in issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
only take place when the defining macros appear at top-level.
(2) Remove the language on p. 145 of CLtL, which states that macro
functions are always defined in the null lexical environment. Clarify
that all defining macros which create functional objects (including
DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
DEFSETF, as well as DEFUN) must ensure that those functions are
defined in the lexical environment in which the defining form is
evaluated.
(3) Specify that top-level forms in a file being compiled are
guaranteed to be processed sequentially. The order in which
non-top-level subforms of a top-level form are processed by the
compiler is explicitly left unspecified.
Rationale:
This proposal makes the rules for when defining macros cause
compile-time side effects to be exactly the same as the rules for when
(EVAL-WHEN (COMPILE) ...) causes compile-time evaluation. This
provides a simple implementation technique.
Item (3) serves two purposes. First, it guarantees users that
compile-time side-effects from top-level EVAL-WHEN forms or defining
macros will happen in the correct order; programmers can depend upon
the compile-time side-effects of a top-level form being visible during
the compilation of subsequent forms. Second, it allows compilers to
perform certain kinds of source-to-source transformations that change
the order of subforms.
For instance, the following example from CLtL
(let ((old-count *access-count*))
(unwind-protect
(progn
(incf *access-count*)
(perform-access))
(setq *access-count* old-count)))
is entirely equivalent to:
(let ((old-count *access-count*))
(let ((thunk #'(lambda () (setq *access-count* old-count))))
(unwind-protect
(progn
(incf *access-count*)
(perform-access))
(funcall thunk))))
(This is a real example from the A-Lisp compiler, which implements
UNWIND-PROTECT by having it push a "thunk" to perform the cleanup
actions onto the catch stack before executing the protected form.)
Current Practice:
Most implementations do allow defining macros in non-top-level places.
However, the rules for when they cause compile-time side-effects are
not always the same as those for EVAL-WHEN. This is the case in
Lucid Common Lisp, for example.
Cost to implementors:
Implementations that currently don't compile defining macros correctly
when they appear at non-top-level will have to be changed.
Cost to users:
None. This is a compatible extension.
Benefits:
The notion of defining macros as being somehow special when they
appear at top-level is removed, since their behavior can be explained
using EVAL-WHEN as a primitive. Allowing defining macros to appear
anywhere instead of restricting them to certain positions results in a
cleaner language design.
Discussion:
This proposal is consistent with the behavior specified in proposal
EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL. In particular, if the compile
time side-effects for defining macros specified in proposal
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY are implemented using
EVAL-WHEN, the "right" compiler behavior for defining macros at
non-top-level will happen automatically.
∂13-Mar-89 1545 X3J13-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 15:45:11 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA09664; Mon, 13 Mar 89 16:42:59 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02574; Mon, 13 Mar 89 16:42:54 -0700
Date: Mon, 13 Mar 89 16:42:54 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132342.AA02574@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 6
This issue has been giving us a lot of trouble for a long time. A few
people on the cl-compiler mailing list have expressed discontent with
the proposals included here, but the dissenters haven't been able to
come up with an acceptable alternative proposal that they can all agree
on.
Issue: EVAL-WHEN-NON-TOP-LEVEL
Forum: Compiler
References: EVAL-WHEN (CLtL pp69-70),
Issue DEFINING-MACROS-NON-TOP-LEVEL
Issue COMPILED-FUNCTION-REQUIREMENTS
Issue IN-PACKAGE-FUNCTIONALITY
Issue LOCALLY-TOP-LEVEL
Category: CLARIFICATION/CHANGE
Edit History: 06-May-88, Version 1 by Sandra Loosemore
16-Dec-88, Version 2 by Loosemore (alternate direction)
30-Dec-88, Version 3 by Loosemore (minor wording changes)
07-Jan-89, Version 4 by Loosemore (update discussion)
09-Feb-89, Version 5 by Pitman and Moon (some major changes)
09-Mar-89, Version 6 by Loosemore (clean up wording)
Status: Ready for release
Problem Description:
The current description of how the compiler should handle EVAL-WHEN
only makes sense when it appears as a top-level form in the file being
compiled. Is it legitimate for EVAL-WHEN to appear in non-top-level
locations? Even if it is legitimate, what does it mean?
Another issue, referred to here as ``the EVAL-WHEN shadowing problem,''
is that some people have complained that shadowing the symbols EVAL,
COMPILE, or LOAD means that you have to also either shadow EVAL-WHEN
and define it to recognize the new symbol, or else you must resign
yourself to writing (EVAL-WHEN (... LISP:EVAL ...) ...),etc. all over.
While the goal here is not to solve this problem, it might be possible
to solve both problems at once.
There are two proposals presented here, GENERALIZE-EVAL and
GENERALIZE-EVAL-NEW-KEYWORDS.
Background/Analysis:
The proposal which follows was constructed with the following goals
in mind:
1. The lexical and dynamic environment for the EVAL-WHEN body should
be the same for each situation. That is, the body should ``mean
the same thing'' regardless of which situation is being processed.
2. The evaluation context for EVAL-WHEN should be the current
lexical environment.
3. At execution time, EVAL-WHEN should always return the result of
its last form if execution of the body occurred, or NIL if the
body was not executed.
4. If a top-level EVAL-WHEN has a LOAD keyword, its body should
inherit top-level-ness during normal processing. This permits the
use of (EVAL-WHEN (EVAL COMPILE LOAD) ...) at top-level to mean
simply "Do whatever would normally be done for this body, but
also do something at compile time." This, in turn, will later be
the key to allowing defining forms to be usefully described in
terms of EVAL-WHEN.
5. Non-top-level expressions should have no effect until they are
executed. This is the key to making sure that any necessary
environment is present. Since the COMPILE keyword forces effects
to occur earlier than execution time, it follows from this that
any correct solution must not allow the COMPILE keyword to have
an effect at other than top-level.
To accomplish these goals, we formulated the following model:
The purpose of EVAL-WHEN is to accomodate the fact that some of the
semantic processing of an expression may usefully be partitioned
between compile time and run time in some circumstances.
(EVAL-WHEN (EVAL) <code>)
describes a general technique for accomplishing some particular goal
at normal program execution time. However, the pair of expressions
(EVAL-WHEN (COMPILE) <code-A>)
(EVAL-WHEN (LOAD) <code-B>)
can be used to describe an alternate technique for implementing part
of the effect (A) at compile-time, and part of the effect (B) at
load-time.
Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL):
Replace the description of EVAL-WHEN with the following:
EVAL-WHEN ({situation}*) {form}* [Special Form]
The body of an EVAL-WHEN form is processed as an implicit PROGN, but
only in the situations listed. Each SITUATION must be a symbol,
either COMPILE, LOAD, or EVAL.
The use of COMPILE and LOAD controls whether and when processing
occurs for top-level forms. The use of EVAL controls whether
processing occurs for non-top-level forms.
The EVAL-WHEN construct may be more precisely understood in terms of
a model of how the file compiler, COMPILE-FILE, processes forms in a
file to be compiled.
Successive forms are read from the file by the file compiler using
READ. These top-level forms are normally processed in what we call
`not-compile-time' mode. There is one other mode, called
`compile-time-too' mode, which can come into play for top-level
forms. The EVAL-WHEN special form is used to annotate a program
in a way that allows the program doing the processing to select
the appropriate mode.
Processing of top-level forms in the file compiler works as follows:
* If the form is a macro call, it is expanded and the result is
processed as a top-level form in the same processing mode
(compile-time-too or not-compile-time).
* If the form is a PROGN form, each of its body forms is
sequentially processed as top-level forms in the same processing
mode.
* If the form is a COMPILER-LET, MACROLET, or SYMBOL-MACROLET,
the file compiler makes the appropriate bindings and recursively
processes the body forms as an implicit top-level PROGN with those
bindings in effect, in the same processing mode.
* If the form is an EVAL-WHEN form, it is handled according to
the following table:
COMPILE LOAD EVAL compile-time-too Action
Yes Yes -- -- Process body in compile-time-too mode
No Yes Yes Yes Process body in compile-time-too mode
No Yes Yes No Process body in not-compile-time mode
No Yes No -- Process body in not-compile-time mode
Yes No -- -- Evaluate body
No No Yes Yes Evaluate body
No No Yes No do nothing
No No No -- do nothing
"Process body" means to process the body as an implicit top-level
PROGN. "Evaluate body" means to evaluate the body forms as in
implicit PROGN in the dynamic execution context of the compiler and
in the lexical environment in which the EVAL-WHEN appears.
* Otherwise, the form is a top-level form that is not one of the
special cases. If in compile-time-too mode, the compiler first
evaluates the form and then performs normal compiler processing
on it. If in not-compile-time mode, only normal compiler
processing is performed. [The nature of this processing is
defined more precisely in issue COMPILED-FUNCTION-REQUIREMENTS.]
Any subforms are treated as non-top-level forms.
For an EVAL-WHEN form that is not a top-level form in the file compiler
(that is, one of: in the interpreter; in COMPILE; or in the file
compiler but not at top-level), if the EVAL situation is specified,
its body is treated as an implicit PROGN. Otherwise, the EVAL-WHEN
form returns NIL.
Clarifications/Consequences:
The following effects are logical consequences of the above proposal:
* It is never the case that the execution of a single EVAL-WHEN
expression will execute the body code more than once.
* The keyword `EVAL' is a misnomer because execution of
the body need not be done by EVAL. In compiled code, such as
(DEFUN FOO () (EVAL-WHEN (EVAL) (PRINT 'FOO)))
the call to PRINT should be compiled.
* Macros intended for use in top-level forms should arrange for all
side-effects to be done by the forms in the macro expansion.
The macro-expander itself should not do the side-effects.
Wrong: (defmacro foo ()
(really-foo)
`(really-foo))
Right: (defmacro foo ()
`(eval-when (compile eval load) (really-foo)))
Adherence to this convention will mean that such macros will behave
intuitively when placed in non-top-level positions.
* Placing a variable binding around an EVAL-WHEN reliably captures the
binding because the `compile-time-too' mode cannot occur (because
introducing a variable binding would mean we were not at top level).
For example,
(LET ((X 3))
(EVAL-WHEN (EVAL LOAD COMPILE) (PRINT X)))
will print 3 at execution [load] time, and will not print anything at
compile time. This is important so that expansions of DEFUN and
DEFMACRO can be done in terms of EVAL-WHEN and can correctly capture
the lexical environment.
(DEFUN BAR (X) (DEFUN FOO () (+ X 3)))
might expand into
(DEFUN BAR (X)
(PROGN (EVAL-WHEN (COMPILE)
(COMPILER::NOTICE-FUNCTION-DEFINITION 'FOO '(X)))
(EVAL-WHEN (EVAL LOAD)
(SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))))
which would be treated the same as
(DEFUN BAR (X)
(SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))
by the above rules.
Test Cases:
;; #1: The EVAL-WHEN in this case is not at top-level, so only the EVAL
;; keyword is considered. At compile time, this has no effect.
;; At load time (if the LET is at top level), or at execution time
;; (if the LET is embedded in some other form which does not execute
;; until later) this sets (SYMBOL-FUNCTION 'FOO1) to a function which
;; returns 1.
(LET ((X 1))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO1) #'(LAMBDA () X))))
;; #2: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting
;; (SYMBOL-FUNCTION 'FOO2) to a function which returns 2.
(EVAL-WHEN (EVAL LOAD COMPILE)
(LET ((X 2))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO2) #'(LAMBDA () X)))))
;; #3: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting the
;; function cell of FOO3 to a function which returns 3.
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO3) #'(LAMBDA () 3)))
;; #4: This always does nothing. It simply returns NIL.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (COMPILE)
(PRINT 'FOO4)))
;; #5: If this form occurs at top-level of a file to be compiled, FOO5 is
;; printed at compile time. If this form occurs in a non-top-level
;; position, nothing is printed at compile time. Regardless of context,
;; nothing is ever printed at load time or execution time.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (EVAL)
(PRINT 'FOO5)))
;; #6: If this form occurs at top-level of a file to be compiled, FOO6 is
;; printed at compile time. If this form occurs in a non-top-level
;; position, nothing is printed at compile time. Regardless of context,
;; nothing is ever printed at load time or execution time.
(EVAL-WHEN (EVAL LOAD)
(EVAL-WHEN (COMPILE)
(PRINT 'FOO6)))
Rationale:
This is compatible with any guarantees made by CLtL, and extends the
behavior usefully to non-top-level situations.
This gives a useful meaning to EVAL-WHEN that supports useful and
predictable behavior if defining macros are used in a non-top-level
situation.
Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS):
As in GENERALIZE-EVAL, but rename the EVAL keyword to :EXECUTE,
the COMPILE keyword to :COMPILE-TOPLEVEL, and LOAD keyword to
:LOAD-TOPLEVEL.
Deprecate the use of keywords EVAL, COMPILE, and LOAD to EVAL-WHEN.
For compatibility, they are supported in EVAL-WHEN
at top-level, but their meaning is not defined elsewhere.
Rationale:
The fact that the situation keywords chosen are not the same as
those now used means that the change can be added in a way that
is truly upward compatible (not only with CLtL but with existing
practice in implementations which have chosen to extend or `clarify'
the definition given in CLtL) since the meaning of EVAL, COMPILE,
and LOAD in non-top-level situations (which was never spelled
out in CLtL) can legitimately differ from the meaning of these
new keywords.
Using other names and/or the keyword package for the names of
situations solves the EVAL-WHEN shadowing problem.
The name `execute' does not promote the confusion that the body of an
EVAL-WHEN must be executed only in the evaluator. It also does not
promote the confusion that the body of an EVAL-WHEN, regardless of when
executed, must run interpreted.
The names `compile-toplevel' and `load-toplevel' emphasize the fact
that these cases are not interesting in non-top-level positions.
Current Practice:
In Symbolics Genera, the interpreter permits EVAL-WHEN in non-top-level
positions in a way that is compatible with this proposal but both the
COMPILE and COMPILE-FILE functions complain about EVAL-WHEN in a
non-top-level position.
Both Lucid Common Lisp and Kyoto Common Lisp already interpret the
EVAL keyword to mean "execute" in non-top-level situations. Both of
these implementations also make (EVAL-WHEN (LOAD) ...) suppress
compile-time "magic" from defining macros such as DEFMACRO.
IIM describes its EVAL-WHEN as:
(defmacro eval-when (situations &body body &environment env)
(if (not (compiler-environment-p env))
(when (member 'eval situations) `(progn ,@body))
(progn
(when (member 'compile situations)
(if (compiler-at-top-level-p env)
(mapc #'eval body)
(warn "Top-level form encountered at non-top-level.")))
(when (member 'load situations) `(progn ,@body)))))
Note that the interpretation of the EVAL situation and the nesting
behavior is different.
Cost to Implementors:
The actual change to EVAL-WHEN in both cases is probably fairly
localized and straightforward to make in most or all implementations.
The second-order costs of proposal GENERALIZE-EVAL will vary depending
on whether existing implementations have extended the definition of
EVAL-WHEN in incompatible ways. If an implementation has made such
extensions, there may be user and system code which depends on them
and the cost of converting that code may be non-trivial. There is
presumably also documentation impact.
Proposal GENERALIZE-EVAL-NEW-KEYWORDS avoids most or all of the
second-order costs of proposal GENERALIZE-EVAL.
The compiler processing for top-level forms might be implemented
something like:
;;; Forms read by the file compiler are passed to PROCESS-TOP-LEVEL-FORM
;;; with a env compile-time-too both NIL.
(defun process-top-level-form (form env compile-time-too)
(setq form (macroexpand form env))
(cond ((not (consp form))
nil)
((eq (car form) 'progn)
(dolist (f (cdr form))
(process-top-level-form f env compile-time-too)))
((eq (car form) 'compiler-let)
(process-compiler-let form env compile-time-too))
((eq (car form) 'macrolet)
(process-macrolet form env compile-time-too))
((eq (car form) 'symbol-macrolet)
(process-symbol-macrolet form env compile-time-too))
((eq (car form) 'eval-when)
(process-eval-when form env compile-time-too))
(t
(if compile-time-too
(internal-eval form env))
(compile-form form env))
))
(defun process-eval-when (form env compile-time-too)
(let* ((situations (cadr form))
(body (cddr form))
(compile-p (member 'compile situations))
(load-p (member 'load situations))
(eval-p (member 'eval situations)))
(cond ((or (and compile-p load-p)
(and eval-p load-p compile-time-too))
(process-top-level-form `(progn ,@body) env t))
(load-p
(process-top-level-form `(progn ,@body) env nil))
((or compile-p
(and eval-p compile-time-too))
(dolist (f body)
(internal-eval f env)))
(t
nil))))
;;; PROCESS-COMPILER-LET, PROCESS-MACROLET, and PROCESS-SYMBOL-MACROLET
;;; do the obvious things.
;;; INTERNAL-EVAL evaluates "form" in lexical environment "env".
Cost to Users:
Technically, none. Either proposal is technically upward compatible
with CLtL.
Proposal GENERALIZE-EVAL might force some extended implementations to
change incompatibly. As such, some users who depend on
implementation-dependent extensions might have to adjust their code
somewhat to deal with those changes.
Proposal GENERALIZE-EVAL-NEW-KEYWORDS does not force implementations
to change incompatibly, so has no forced impact on users.
Cost of Non-Adoption:
EVAL-WHEN is a mess. Using it as the low-level substrate into which
defining macros should expand, and guaranteeing any predictable effects
of those macros in non-top-level situations is currently difficult and
would continue to be so in the absence of some resolution on this issue.
Benefits:
The costs of non-adoption would be avoided: it would be possible to
use EVAL-WHEN in many situations where it cannot currently be used
reliably.
The portability of many existing tools which use EVAL-WHEN internally
in macros will be enhanced.
Aesthetics:
This generalization of the meaning makes the purpose and uses of
EVAL-WHEN less mysterious. In that sense, aesthetics are simplified
somewhat.
Discussion:
The cleanup issue LOCALLY-TOP-LEVEL would make LOCALLY also "pass
through" top-level-ness to its body. The reason why that is not
addressed in this issue is that it involves making LOCALLY a special
form.
Pitman and Moon don't care whether we say `top level,' `top-level,' or
`toplevel.' The spelling choices in this writeup are arbitrary. If
necessary, the proposal GENERALIZE-EVAL-NEW-KEYWORDS could be amended
to propose :COMPILE-TOP-LEVEL, etc.
Pitman, Moon, and Bob Laddaga (a Symbolics Cloe implementor) support
both of these proposals. Pitman and Laddaga have a preference for
GENERALIZE-EVAL-NEW-KEYWORDS. Moon is neutral about which should be
preferred.
Sandra Loosemore says:
I still feel somewhat uncomfortable with the definition of EVAL-WHEN
presented here, mostly because its nesting behavior is so unintuitive
(as in test case number 6). We have also had a hard time in deciding
what the term "top-level" really means; the definition presented here
is rather arbitrary. However, since we have run out of time in which
to come up with acceptable alternatives, I'm willing to go along with
proposal GENERALIZE-EVAL. It is compatible with the description in
CLtL but presented in a more coherent way, and I think it is an
improvement. On the other hand, I don't really like the idea of
changing the names of the keywords; if we are going to make an
incompatible change, the right thing to do would be to throw out
EVAL-WHEN entirely and start from scratch.
∂13-Mar-89 1601 X3J13-mailer **DRAFT** issue MACRO-ENVIRONMENT-EXTENT, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 15:57:19 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA10215; Mon, 13 Mar 89 16:55:08 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02585; Mon, 13 Mar 89 16:55:05 -0700
Date: Mon, 13 Mar 89 16:55:05 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132355.AA02585@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue MACRO-ENVIRONMENT-EXTENT, version 3
This issue is still under discussion. There are three proposals
presented formally and two more mentioned informally in the discussion
section, but it appears that the decision is really between proposal
DYNAMIC and everything else.
Forum: Compiler
Issue: MACRO-ENVIRONMENT-EXTENT
References: CLtL p. 145-146
Issue COMPILER-LET-CONFUSION
Issue MACRO-CACHING
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue SYNTACTIC-ENVIRONMENT-ACCESS
CLOS Chapter 3 (89-003)
Category: CLARIFICATION,CHANGE
Edit History: V1, 10 Jan 1989, Sandra Loosemore
V2, 09 Mar 1989, Sandra Loosemore
V3, 13 Mar 1989, Sandra Loosemore (last-minute discussion)
Status: **DRAFT**
Problem Description:
What is the extent of environment objects received as the &ENVIRONMENT
argument of a macro function?
CLtL says that &ENVIRONMENT is "useful primarily in the rare cases
where a macro definition must explicitly expand any macros in a
subform of the macro call before computing its own expansion". While
this suggests that macro environment objects are typically used within
the dynamic scope of the macro function, the use of the word
"primarily" (rather than "only" or "exclusively" or some similarly
strong language) suggests that there may be other legitimate uses for
environment objects. But, because CLtL is silent about what those
uses might be, many users and implementors are under the impression
that environment objects have only dynamic extent.
There are some situations where using environment objects as if they
had indefinite extent provides a very useful viewpoint from which to
solve a problem. Consider the following example:
(defmacro typed-var (var) var)
(defmacro local-type-declare (declarations &body forms &environment env)
`(macrolet ((typed-var (&whole w var)
(let ((type (assoc var ',declarations)))
(if type
`(the ,(cadr type) ,var)
(macroexpand w ',env)))))
,@forms))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
Here, local macro TYPED-VAR is defined to look first in the innermost
lexical environment for information about the variable, and if there
isn't any then it recurses on the next outermost lexical environment.
The global definition of TYPED-VAR provides a terminal case to stop
the recursion.
There are other situations where the extent of macro environment
objects comes into play. For example, if we allow caching of macro
expansions (issue MACRO-CACHING), environments must have indefinite
extent. It is unclear whether CLOS would be affected by allowing
macro environments to have only dynamic extent. (The descriptions of
the CLOS defining macros in document 89-003 seem to imply that the
value of the &ENVIRONMENT argument appears in the expansion of the
macro, but there now seems to be sentiment that the model of how the
defining macros work that is presented there is broken.)
Proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE:
State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or as the argument to a *MACROEXPAND-HOOK*
function have indefinite extent.
Note that implementations are not permitted to destructively modify
lexical information in environment objects once they have been passed
to a macro function. It is, however, permissible to add or remove
global definitions that are accessible through the environment.
Rationale:
This legitimizes the use of idioms which depend on macro environments
having indefinite extent.
Since data objects in Lisp otherwise have indefinite extent, it is
more consistent to give environment objects indefinite extent as
well.
Proposal MACRO-ENVIRONMENT-EXTENT:DYNAMIC:
State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or with a *MACROEXPAND-HOOK* function
have only dynamic extent; the consequences are undefined if they are
referred to outside the dynamic extent of that macro function or hook
function.
Rationale:
This allows implementations to use somewhat more efficient techniques
for representing environment objects. For example, the storage could
be stack-allocated, or environments could be bashed destructively
instead of always being freshly heap-allocated.
Proposal MACRO-ENVIRONMENT-EXTENT:DYNAMIC-WITH-COPIER:
State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or with a *MACROEXPAND-HOOK* function
have only dynamic extent; the consequences are undefined if they are
referred to outside the dynamic extent of that macro function or hook
function.
Add a new function:
COPY-ENVIRONMENT environment [function]
This function returns an environment object that is semantically
equivalent to "environment" (which must be an object of the type
received with an &ENVIRONMENT argument to a macro or as an argument to
a *MACROEXPAND-HOOK* function), but which may safely be referred to
outside the dynamic extent of the macro function. This function is
permitted to return an object that is EQ to its argument if that
object may be safely used.
Rationale:
This allows implementations to use somewhat more efficient techniques
for representing environment objects. For example, the storage could
be stack-allocated, or environments could be bashed destructively
instead of always being freshly heap-allocated.
It also allows programmers to use idioms that rely on environment
objects having indefinite extent.
Current Practice:
Macro environments appear to have indefinite extent in Lucid Common
Lisp, Kyoto Common Lisp, CMU Common Lisp (at least in the
interpreter), Utah Common Lisp, and A-Lisp. A-Lisp internally uses
the kind of idiom shown in the example above to implement FLET,
LABELS, and FUNCTION as macros.
Macro environments are stack-allocated in Symbolics Genera, and hence
have dynamic extent.
Macro environments also have dynamic extent on the TI Explorer,
because the compiler uses special variables are used to keep track of
lexical definitions.
Cost to implementors:
For proposal INDEFINITE, some implementations would need to change. A
simple implementation of macro environments that would fit the
requirements of this proposal is to represent them as lists, pushing
information for inner contours onto the front of the list as the
contour is entered and popping the list when the contour is exited.
For proposal DYNAMIC, there is no associated implementation cost.
For proposal DYNAMIC-WITH-COPIER, the implementation cost is unknown
but probably fairly small in most implementations.
Cost to users:
For proposal INDEFINITE, there is no associated cost to users.
For proposal DYNAMIC, users would not be able to portably use a
simple and elegant approach to solving certain kinds of problems.
For proposal DYNAMIC-WITH-COPIER, users would have to remember to make
a copy of an environment object in some situations.
Benefits:
It is made clear whether treating environment objects as if they had
indefinite extent is portable usage.
Discussion:
Proposal SYNTACTIC-ENVIRONMENT-ACCESS:ADD-FUNCTIONAL-INTERFACE
includes adding a function called AUGMENT-ENVIRONMENT which could also
be used to create a copy of an environment. However, it returns an
object with the same extent as its argument, and therefore can not
replace the function COPY-ENVIRONMENT under proposal
DYNAMIC-WITH-COPIER.
We have also considered a couple of other alternatives on this
issue.
One alternative would be to give "remote" environments created by
COMPILE-FILE the extent of that call to COMPILE-FILE, while "local"
environments (the null lexical environment and environments created by
COMPILE and EVAL) would have indefinite extent.
Another alternative would be to say that environments created by
COMPILE-FILE, COMPILE, or EVAL have a dynamic extent that includes the
time when any other macro calls appearing lexically within the
expansion returned by the macro function are expanded. This is
similar to the extent of the special bindings made by COMPILER-LET.
Both of these proposals could be combined with adding a copier
function to deal with those implementations where environments are
stack-allocated. They would both solve the extent problem for the
example given in the problem description section, but not the general
problem of macro caching. In conjunction with the proposals for issue
SYNTACTIC-ENVIRONMENT-ACCESS, they would both require some
modifications to implementations that currently give macro
environments dynamic extent.
Loosemore supports proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE.
Moon says:
My opinion is that anything in CLOS that seems to depend on indefinite
extent for macro environments is broken and needs to be fixed. It's not
broken because of the environment extent, but for other reasons.
Thus I believe in dynamic extent for environments.
Neil Goldman says:
In my code walker I have a pretty ugly way of dealing with MACROLET
that would have been trivial if I could have counted on the
ENVIRONMENT having indefinite extent. There may be some cleaner way
than what I did, but I just looked at PCL's code walker, and it also
is much more complex than would be necessary if environments had
indefinite extent.
∂13-Mar-89 1610 X3J13-mailer **DRAFT** issue PROCLAIM-ETC-IN-COMPILE-FILE (version 4)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 16:10:26 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA10862; Mon, 13 Mar 89 17:08:13 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02608; Mon, 13 Mar 89 17:08:10 -0700
Date: Mon, 13 Mar 89 17:08:10 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903140008.AA02608@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue PROCLAIM-ETC-IN-COMPILE-FILE (version 4)
This is a new writeup for an issue that was first brought up several
months ago. We haven't had time to review it thoroughly yet.
Issue: PROCLAIM-ETC-IN-COMPILE-FILE
References: CLtL p. 182 [package functions],
p. 156 [PROCLAIM], p. 439 [COMPILE-FILE];
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue IN-PACKAGE-FUNCTIONALITY
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CLARIFICATION, CHANGE, ADDITION
Edit History: 15 Sep 88, V1 by David Gray
23 Sep 88, V2 by Sandra Loosemore (summarize discussion)
11 Mar 89, V3 by Sandra Loosemore (rewrite)
13 Mar 89, V4 by Sandra Loosemore (discussion)
Status: **DRAFT**
Problem Description:
Should the compiler treat top-level calls to PROCLAIM specially?
Page 182 of CLtL says that COMPILE-FILE needs to treat top-level calls
to the following package functions as though they were wrapped in an
(EVAL-WHEN (COMPILE LOAD EVAL) ...):
EXPORT IMPORT IN-PACKAGE MAKE-PACKAGE SHADOW
SHADOWING-IMPORT UNEXPORT UNUSE-PACKAGE USE-PACKAGE
CLtL is silent on whether top-level calls to PROCLAIM should also be
evaluated at compile-time, which presumably means they shouldn't be.
However, some implementations do evaluate PROCLAIM at compile-time.
In the model of how COMPILE-FILE works that is presented in issues
EVAL-WHEN-NON-TOP-LEVEL and DEFINING-MACROS-NON-TOP-LEVEL, the special
form EVAL-WHEN is the only thing that can cause compile-time evaluation
to occur. The compile-time side-effects of macros such as DEFMACRO
and DEFPACKAGE are explained by having them include EVAL-WHEN in their
expansions. Any functions that are treated specially, however, must
be included as special cases in the compiler.
Proposal IN-PACKAGE-FUNCTIONALITY:NEW-MACRO would remove the
requirement that the package functions be treated specially. Do we
wish to make an exception to the model for PROCLAIM?
Proposal PROCLAIM-ETC-IN-COMPILE-FILE:YES:
Require COMPILE-FILE to treat top-level calls to PROCLAIM as if they
were wrapped in an (EVAL-WHEN (COMPILE LOAD EVAL) ...).
Rationale:
Proclamations affect compilation semantics and should be made
available to the compiler.
Proposal PROCLAIM-ETC-IN-COMPILE-FILE:NO:
Clarify that calls to PROCLAIM should be treated the same as any
other function call. Users should wrap an explicit EVAL-WHEN around
top-level calls to PROCLAIM if they want them to affect compilation.
Rationale:
This makes the semantics of COMPILE-FILE more uniform and easier
to understand. In particular, if we remove the magic compile-time
behavior of the package functions, it seems silly to add another
exception for PROCLAIM.
Proposal PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO:
Add a new macro:
DEFPROCLAIM &rest decl-specs [Macro]
This macro PROCLAIMs the given <decl-specs>, which are not
evaluated. If a call to this macro appears at top-level in a file
being processed by the file compiler, the proclamations are also
made at compile-time. As with other defining macros, it is
unspecified whether or not the compile-time side-effects of a
DEFPROCLAIM persist after the file has been compiled.
Clarify that calls to PROCLAIM should be treated the same as any
other function call. Users should wrap an explicit EVAL-WHEN around
top-level calls to PROCLAIM if they want them to affect compilation,
or use the macro DEFPROCLAIM.
Rationale:
The macro makes the proclamations available to the compiler in such
a way that does not require any special exceptions to be made in
the model of how COMPILE-FILE works.
Current Practice:
The TI explorer apparently implements proposal YES, except that
(EVAL-WHEN (LOAD) (PROCLAIM '(OPTIMIZE ...))) doesn't do anything.
The Symbolics compiler has special top-level handling for PROCLAIM,
although the details are not clear.
Lisps developed at Utah (UCL, A-Lisp, PSL/PCLS) do not give PROCLAIM
any special compile-time handling.
Lucid does not evaluate calls to PROCLAIM at compile-time.
The IIM compiler has special top-level handling for PROCLAIM when
the argument is a constant. The information is recorded in the remote
environment.
Cost to implementors:
Since implementations are already required to have a mechanism for
compile-time handling of the package functions, it would probably
only require minor adjustments to add handling for PROCLAIM.
Cost to users:
For proposal YES, users would have no way to suppress compile-time
evaluation of a top-level call to PROCLAIM. Wrapping it in an
(EVAL-WHEN (EVAL LOAD)...) wouldn't work under the model of how
EVAL-WHEN works in proposal EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL.
Under any of these proposals, some users would probably have to
make minor changes to their code.
Benefits:
Users will know what to expect when they use PROCLAIM.
Costs of Non-Adoption:
Users will not know what to expect when they use PROCLAIM.
Aesthetics:
At least two people consider requiring magic behavior for certain
top-level function calls to be "semantically bletcherous". Removing
all special cases for functions that are implicitly evaluated at
compile-time would simplify the model of how COMPILE-FILE works.
Programs look cleaner if EVAL-WHEN is only needed for unusual cases
instead of being required for the normal cases.
Discussion:
The first version of this writeup also included REQUIRE with PROCLAIM,
but we have now voted to remove REQUIRE from the language entirely.
It also specified that OPTIMIZE proclamations should only have a local
effect within the file being compiled. This was removed for
consistency with other compile-time side-effects (such as those from
DEFMACRO), where their persistence is explicitly left unspecified.
Loosemore favors proposal NO, but wouldn't oppose proposal NEW-MACRO.
Kim Barrett says:
Proposal YES violates the general approach we've been taking of trying
to limit side-effects on the local environment during compilation.
Proposal NO makes PROCLAIM virtually worthless.
Proposal NEW-MACRO -- While this matches up with other stuff we've
been doing, I'm concerned about two things. First, I really dislike
the name DEFPROCLAIM. This thing isn't defining anything! It sounds
like something that modifies the behavior of PROCLAIM, not something
that actually makes a proclamation. Second, I'm concerned about the
cost to users. I think the statement that
"Under any of these proposals, some users would probably have to make
minor changes to their code."
is rather misleading for this case. There are a lot of PROCLAIMs out
there.
Loosemore replies:
....but all of those uses of PROCLAIM are already nonportable. No
matter what we do here, somebody is going to get burned.
Suggestions for better names for the macro are welcome.
∂13-Mar-89 1627 X3J13-mailer issue WITH-COMPILATION-UNIT, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 16:27:44 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA11422; Mon, 13 Mar 89 17:25:34 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02634; Mon, 13 Mar 89 17:25:31 -0700
Date: Mon, 13 Mar 89 17:25:31 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903140025.AA02634@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue WITH-COMPILATION-UNIT, version 3
Forum: Compiler
Issue: WITH-COMPILATION-UNIT
References: COMPILE (p438), COMPILE-FILE (p439)
Category: ADDITION
Edit history: 29-Sep-88, Version 1 by Pitman
10-Mar-89, Version 2 by Pitman (merge comments)
13-Mar-89, Version 3 by Loosemore (update discussion)
Status: Ready for release
Problem Description:
Some actions done by the compiler (and particularly the file compiler)
are typically deferred until the "very end" of compilation. For example,
some compilers complain about "functions seen but not defined".
Unfortunately, since COMPILE-FILE is the largest unit of granularity,
and since systems often extend over more than one file, it often happens
that the compiler needlessly complains at the end of compiling one file
about the absence of functions defined in the next file.
Proposal (WITH-COMPILATION-UNIT:NEW-MACRO):
Add the following new macro:
WITH-COMPILATION-UNIT options &BODY forms [Macro]
Executes forms from left to right. Within the dynamic context
of this form, actions deferred by the compiler until "the end of
compilation" will be deferred until the end of the outermost call
to WITH-COMPILATION-UNIT. The result(s) are the same as that of
the last of the FORMS (or NIL if FORMS is null).
OPTIONS is a keyword/value list, where only the values are
evaluated. The set of keywords permitted may be extended by the
implementation, but the only keyword defined by this standard is:
:OVERRIDE boolean
The default is NIL. If nested dynamically only the outer call
to WITH-COMPILATION-UNIT has any effect unless BOOLEAN is T,
in which case warnings are deferred only to the end of the
innermost call.
It follows that the functions COMPILE and COMPILE-FILE should
provide the effect of (WITH-COMPILATION-UNIT (:OVERRIDE NIL) ...)
around their code.
Any implementation-dependent extensions may only be provided
as the result of an explicit programmer request by use of
an implementation-dependent keyword. Implementations are forbidden
from attaching additional meaning to a conforming use of this
macro.
Note also that not all warnings are deferred. In some implementations,
it may be that none are deferred. This proposal only creates an
interface to the capability where it exists, it does not require the
creation of the capability. An implementation which does not do
deferred warnings may correctly implement this as expanding into PROGN.
Test Case:
(DEFUN COMPILE-FILES (&REST FILES)
(WITH-COMPILATION-UNIT ()
(MAPCAR #'(LAMBDA (FILE) (COMPILE-FILE FILE)) FILES)))
(COMPILE-FILES "A" "B" "C")
processes deferred warnings only after compiling all of A, B, and C.
Rationale:
This will make the development of portable system-construction tools
considerably more convenient.
Current Practice:
Lucid has a very similar facility, called WITH-DEFERRED-WARNINGS.
TI Explorer and Symbolics Genera have a similar facility, which they
call COMPILER-WARNING-CONTEXT-BIND.
Cost to Implementors:
In implementations which have no deferred warnings, there is no cost.
In implementations which have deferred warnings, the cost is probably
fairly small -- usually just a matter of writing interfacing the
proposed macro to an existing one.
Cost to Users:
None. This is a compatible addition.
Cost of Non-Adoption:
Portable system-construction tools would continue to print lots of
spurious warnings because they would have no way to tell the system
that a set of files was working together.
Benefits:
The cost of non-adoption is avoided.
Aesthetics:
The ability to create a compilation unit other than a file is important.
Discussion:
Pitman and Benson support this addition.
One could imagine adding more options at a later date.
It was the opinion of the compiler committee that there was room for
expansion here to address issues like bounding the scope of global
proclamations, sharing compile-time environments across files, etc.
However, insufficient work was done on this to justify putting such
a thing into the standard. The only clear need we have at this time
was to defer warnings, but we chose a general name like
WITH-COMPILATION-UNIT rather than a specific name like Lucid's
WITH-DEFERRED-WARNINGS in order to encourage implementations to
experiment with other kinds of options under implementation-specific
keywords. Perhaps by the time of the next standard there will be
sufficient understanding of this area to warrant further elaboration
of this primitive.
Kim Barrett says:
I strongly oppose the behavior you proposed for compile and
compile-file. It is my belief that whether to override or not must be
controlled through an argument to the compile functions, with the
default being to override. Otherwise, all existing code which makes
use of the compile functions must be modified to protect itself by
wrapping a (with-compilation-unit (:override t) ...) around the calls
to the compiler.
Consider a stream system built on an object system which will compose
and compile functions on the fly on an as needed basis. It would be
very strange for the functions so generated while doing file io for
the user's compile-file to have any relationship with said
compile-file.
I agree with your position that implementation-dependent extensions
must be explicitly requested.
∂13-Mar-89 1622 X3J13-mailer **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 16:22:04 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA11265; Mon, 13 Mar 89 17:19:53 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02631; Mon, 13 Mar 89 17:19:48 -0700
Date: Mon, 13 Mar 89 17:19:48 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903140019.AA02631@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
This issue is also still under discussion. This version of the writeup
is fairly new and hasn't been reviewed thoroughly yet.
Forum: Compiler
Issue: SYNTACTIC-ENVIRONMENT-ACCESS
References: CLtL Chapter 8: Macros,
Issue MACRO-FUNCTION-ENVIRONMENT,
Issue GET-SETF-METHOD-ENVIRONMENT,
Issue COMPILE-FILE-ENVIRONMENT
Related Issues: Issue FUNCTION-NAME,
Issue PROCLAIM-LEXICAL
Issue MACRO-ENVIRONMENT-EXTENT
Category: ADDITION
Edit history: Version 1, 2-Oct-88, Eric Benson
Version 2, 17-Feb-89, Kim A. Barrett
Version 3, 9-Mar-89, Kim A. Barrett (respond to comments)
Version 4, 12-Mar-89, Sandra Loosemore (more revisions)
Status: **DRAFT**
Problem description:
When macro forms are expanded, the expansion function is called with
two arguments: the form to be expanded, and the environment in which
the form was found. The environment argument is of limited utility.
The only use sanctioned currently is as an argument to MACROEXPAND or
MACROEXPAND-1 or passed directly as an argument to another macro
expansion function. Recent cleanup issues propose to allow it as an
argument to MACRO-FUNCTION and to GET-SETF-METHOD.
It is very difficult to write a code walker that can correctly handle
local macro and function definitions, due to insufficient access to
the information contained in environments and the inability to
augment environments with local definitions.
Some people believe that the CLOS meta-object protocol will require the
ability to distinguish between remote environments used for compiling
to a file, from local environments used for processing by EVAL or
COMPILE. (However, there is no requirement in chapters 1 & 2 of the
CLOS spec that things be done this way.)
There are three proposals; SMALL, MEDIUM, and LARGE.
Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:SMALL):
The following functions provide information about syntactic
environment objects. In all of these functions the argument named ENV
is an environment of the sort received by the &ENVIRONMENT argument to
a macro or as the environment argument for EVALHOOK. Optional "env"
arguments default to NIL, which respresents the local null lexical
environment (containing only global definitions and proclamations
that are present in the runtime environment). All of these functions
should signal an error of type TYPE-ERROR if the value of an
environment argument is not a syntactic environment.
VARIABLE-KIND variable &optional env [Function]
VARIABLE is a symbol. This function returns one of the following
symbols, depending on the type of definition or binding which is
apparent in ENV.
NIL There is no apparent definition or binding for variable.
:SPECIAL VARIABLE refers to a special variable, either declared
or proclaimed.
:LEXICAL VARIABLE refers to a lexical variable.
:SYMBOL-MACRO VARIABLE refers to a SYMBOL-MACROLET binding.
:CONSTANT VARIABLE refers to a named constant, defined by
DEFCONSTANT.
[Note: If issue PROCLAIM-LEXICAL passes, then the :LEXICAL result
will also refer to variables proclaimed lexical.]
Example:
(DEFMACRO KIND-OF-VARIABLE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-KIND VAR ENV))
(DEFVAR A)
(DEFUN TEST ()
(LET (B)
(LET (C)
(DECLARE (SPECIAL C))
(SYMBOL-MACROLET ((D ANYTHING))
(LIST (KIND-OF-VARIABLE A)
(KIND-OF-VARIABLE B)
(KIND-OF-VARIABLE C)
(KIND-OF-VARIABLE D)
(KIND-OF-VARIABLE E))))))
(TEST) -> (:SPECIAL :LEXICAL :SPECIAL :SYMBOL-MACRO NIL)
FUNCTION-KIND function &optional env [Function]
FUNCTION is a function name. This function returns two values,
depending on the type of function definition or function binding
which is apparent for FUNCTION in ENV.
NIL There is no apparent definition for FUNCTION.
:FUNCTION FUNCTION refers to a function.
:MACRO FUNCTION refers to a macro.
:SPECIAL-FORM FUNCTION refers to a special form.
The second value specifies whether the definition is local or
global. If local, the second value is true, and it is false when
the definition is global.
Some function names may refer to both a global macro and a global
special form. In such a case, the macro takes precedence, and
:MACRO is returned as the first value.
[Note: The use of "function name" rather than "symbol" as the
description of the function argument is intended to be compatible
with the various proposals to extend the syntax of function
specifiers. If no such change actually occurs then this would only
refer to symbols.]
Example:
(DEFMACRO KIND-OF-FUNCTION (FUNCTION-NAME &ENVIRONMENT ENV)
`',(FUNCTION-KIND FUNCTION-NAME ENV))
(DEFUN A ())
(DEFMACRO B ())
(DEFUN TEST ()
(FLET ((C ()))
(MACROLET ((D ()))
(MULTIPLE-VALUE-CALL #'LIST
(KIND-OF-FUNCTION A)
(KIND-OF-FUNCTION B)
(KIND-OF-FUNCTION QUOTE)
(KIND-OF-FUNCTION C)
(KIND-OF-FUNCTION D)
(KIND-OF-FUNCTION E)))))
(TEST) -> (:FUNCTION NIL
:MACRO NIL
:SPECIAL-FORM NIL
:FUNCTION T
:MACRO T
NIL NIL)
VARIABLE-TYPE variable &optional env [Function]
VARIABLE is a symbol. This function returns the type specifier
associated with the variable named by the symbol in the environment.
If no explicit association exists, either by PROCLAIM or DECLARE,
then the result is the type specifier T.
The result of this function may not include all the apparent TYPE
declarations for VARIABLE. In particular, an implementation is free
to ignore TYPE declarations, only returning TYPE information which
was added to ENV by a call to AUGMENT-ENVIRONMENT.
Example:
This example assumes that the implementation records type
information in the environment, rather than ignoring it.
(DEFMACRO VARTYPE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-TYPE VAR ENV))
(DEFVAR A 1)
(PROCLAIM '(FIXNUM A))
(DEFUN TEST ()
(LET ((B (AREF "X" 0))
(C 3))
(DECLARE (STRING-CHAR B))
(LIST (VARTYPE A) (VARTYPE B) (VARTYPE C))))
(TEST) -> (FIXNUM STRING-CHAR NIL)
FUNCTION-FTYPE function &optional env [Function]
FUNCTION is a function name. This function returns the functional
type specifier associated with the function in the environment, or
the symbol FUNCTION if there is no functional type declaration or
proclamation associated with the function.
The result of this function may not include all the apparent FTYPE
declarations for FUNCTION. In particular, an implementation is free
to ignore FTYPE declarations, only returning FTYPE information which
was added to ENV by a call to AUGMENT-ENVIRONMENT.
Example:
This example assumes that the implementation records ftype
information in the environment, rather than ignoring it.
(DEFMACRO FUNTYPE (FUN &ENVIRONMENT ENV)
`',(FUNCTION-FTYPE FUN ENV))
(DEFUN A-FUNCTION (X)
(+ X 3))
(PROCLAIM '(FTYPE (FUNCTION (FIXNUM) FIXNUM) A-FUNCTION))
(DEFUN TEST ()
(FLET ((ANOTHER-FUNCTION (X)
(+ X 2)))
(DECLARE (FTYPE (FUNCTION (INTEGER) INTEGER) ANOTHER-FUNCTION))
(LIST (FUNTYPE A-FUNCTION) (FUNTYPE ANOTHER-FUNCTION))))
(TEST) -> ((FUNCTION (FIXNUM) FIXNUM) (FUNCTION (INTEGER) INTEGER))
AUGMENT-ENVIRONMENT env &KEY variable
symbol-macro
function
macro
declare [Function]
This function returns a copy of ENV, augmented with the information
provided by the keyword arguments. The arguments are supplied as
follows:
:VARIABLE A list of symbols which shall be visible as bound
variables in the new environment. Whether each
binding is to be interpreted as special or lexical
depends on SPECIAL declarations recorded in the
environment or provided in the :DECLARE argument list.
:SYMBOL-MACRO A list of symbol macro definitions, in the same format
as the CADR of a SYMBOL-MACROLET special form. The
new environment will have local symbol-macro bindings
of each symbol to the corresponding expansion, so that
MACROEXPAND will be able to expand them properly.
:FUNCTION A list of function names which shall be visible as local
function bindings in the new environment.
:MACRO A list of local macro definitions, in the same format
as the CADR of a MACROLET special form. The new
environment will have local macro bindings of each
name to the corresponding expander function, which
will be returned by MACRO-FUNCTION and used by
MACROEXPAND.
:DECLARE A list of decl-specs. The new environment will
contain information about SPECIAL, TYPE, and FTYPE
declarations appearing within the list.
An error is signalled if any of the symbols naming macros in the
:SYMBOL-MACRO alist are also included in the :VARIABLE list.
An error is signalled if any of the names specified as keys in the
:MACRO alist are also included in the :FUNCTION list. The consequences
of destructively modifying the list structure of any of the arguments
to this function are undefined.
The extent of the returned environment is the same as the extent of
the argument.
While an environment argument from EVALHOOK may be used as the
environment argument for this function, the reverse is not true. If
an attempt is made to use the result of AUGMENT-ENVIRONMENT as
the environment argument for EVALHOOK, the consequences are undefined.
The environment returned by AUGMENT-ENVIRONMENT may only be used for
syntactic analysis, ie. the functions specified by this proposal and
functions such as MACROEXPAND.
[If PROCLAIM-LEXICAL is adopted, LEXICAL declarations would also
be recognized.]
Rationale:
This proposal defines a minimal set of accessors and a constructor
for environments.
The symbol-macro and macrolet definitions and declarations passed
to AUGMENT-ENVIRONMENT are in the same form as those which would
normally be encountered by a code-walker. This makes it easier to
use. In particular, there is no need for users to write their own
code to destructure macro arguments.
Making TYPE and FTYPE information optional continues to allow
implementations the freedom to simply ignore all such declarations.
Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:MEDIUM):
This is the same as proposal SMALL, but also includes:
There are two kinds of environments, local and remote. Local
environments are created by EVAL and COMPILE, and are used in
situations where the information in the environment pertains
to the immediate running Lisp environment. Remote environments
are used by processors such as COMPILE-FILE to model what the
Lisp environment will look like when the code being processed
is actually loaded.
If AUGMENT-ENVIRONMENT receives a remote environment as an argument,
then the new environment returned by this function will also be
remote, and the two will refer to the same model of the remote
environment.
ENVIRONMENT-REMOTE-P env [Function]
Returns true if ENV is a remote environment, false otherwise.
WITH-REMOTE-ENVIRONMENT var &body body [Macro]
Evaluates the BODY forms with VAR bound to a newly created remote
environment. The extent of the environment is the dynamic extent of
the WITH-REMOTE-ENVIRONMENT form.
This is the only specified mechanism by which a new remote
environment may be created.
Rationale:
The notion of local and remote environments may be useful for
developing the CLOS meta-object protocol. At some future time,
we may wish to tighten the specification of how compile-time
definitions of defining macros such as DEFMACRO or DEFCLASS are
achieved, by saying that the compile-time definitions must be made
only in the remote environment.
Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:LARGE):
This is the same as proposal MEDIUM, but also includes:
ENVIRONMENT-PROPERTY env name property &optional default
This function and its SETF method allow the association of arbitrary
'global' properties with names within an environment. An
environment can be thought of as having a local property list
associated with any name, and this function provides access to that
property list.
A remote environment may be thought of as an extension of the local
environment. Thus, when this function is applied to a remote
environment and the property is not found, the global local environment
is then searched.
The association between names and property lists uses EQUAL to match
names. The search of the property list uses EQ to match properties.
If the property is not found, DEFAULT is returned.
Using SETF of ENVIRONMENT-PROPERTY affects all environments which
refer to the same environment model. In particular, if ENV is a
local environment then all local environments are affected, while if
ENV is a remote environment, then all environments refering to the
same remote environment model as the argument are affected.
[Note: The local property list of a name is not necessarily the
symbol-plist of the name, though that is a possible implementation
for names which are symbols.
Note: The use of EQUAL as the matching function for names is to
allow for proposed extensions to function names. If no such
extension occurs, then EQ could be used instead.]
Rationale:
This would provide a mechanism for making and accessing global
definitions in the remote environment.
Cost to Implementors:
Most implementations already record some of this information in some
form. Providing these functions should not be too difficult, but it
is a more than trivial amount of work.
Cost to Users:
This change is upward compatible with user code.
Current practice:
No implementation provides all of this interface currently. Portable
Common Loops defines a subset of this functionality for its code
walker and implements it on a number of diffent versions of Common
Lisp. IIM uses the functionality provided by ENVIRONMENT-REMOTE-P
and ENVIRONMENT-PROPERTY (under other names) to implement the
association between names and remote metaobjects (macro and type
definitions, CLOS remote metaobjects, &etc).
Discussion:
The first version of this proposal expressly did not deal with the
objects which are used as environments by EVALHOOK. This version is
extended to support them in the belief that such environments share a
lot of functionality with the syntactic environments needed by a
compiler. While the two types of environments may have very
different implementations, there are many operations which are
reasonable to perform on either type, including all of the accessor
functions described by this proposal.
AUGMENT-ENVIRONMENT currently requires signaling an error when
symbol-macro names match variable names in the same call. This could
be reduced to "should signal". By requiring the error signaling, this
proposal is compatable with Proposal SYMBOL-MACROLET-DECLARE:ALLOW,
which says
"... signals an error if a SPECIAL declaration names one of the symbols
being defined as a symbol-macrolet."
Maintaining compatability with the SYMBOL-MACROLET-DECLARE proposal
allows fairly trivial implementations of the SYMBOL-MACROLET
special-form in terms of the AUGMENT-ENVIRONMENT function.
An possible alternative syntax for WITH-REMOTE-ENVIRONMENT might be
WITH-REMOTE-ENVIRONMENT (var &key) &body body
Can anyone suggest candidates for keyword options? We could do this
even if we can't think of any immediately, leaving room for
implementation-specific extensions. One candidate option that some
implementations might want would be to specify a target machine for
the compilation.
Kim Barrett originally suggested that WITH-COMPILATION-UNIT should
provide the mechanism for creating new remote environments. However,
it has been suggested that WITH-COMPILATION-UNIT is intended to serve
a somewhat different purpose.
Sandra Loosemore says:
I support proposal SMALL but would vote against both of the larger
proposals. It's true that they provide functionality which *might* be
useful to implement CLOS, but there is nothing now in the standard
that *requires* this functionality to be added. In fact, the version
of issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS that was accepted at
the January meeting explicitly leaves unspecified the mechanism by
which defining macros make definitions available to the compiler. We
have very little practical experience with using environment objects
for this purpose and I think it would be premature to try to
standardize it at this point. In particular, since the meta-object
protocol is still undergoing what appear to be substantial changes,
let's wait until it settles down and then see what kind of compiler
hooks it needs, instead of possibly standardizing the wrong thing.
∂13-Mar-89 1643 X3J13-mailer issue COMPILER-LET-CONFUSION, version 7
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 Mar 89 16:43:27 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Mon, 13 Mar 89 19:39:46 EST
Date: Mon, 13 Mar 89 19:41 EST
From: Barry Margolin <barmar@Think.COM>
Subject: issue COMPILER-LET-CONFUSION, version 7
To: cl-compiler@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132314.AA02546@defun.utah.edu>
Message-Id: <19890314004109.1.BARMAR@OCCAM.THINK.COM>
Date: Mon, 13 Mar 89 16:14:26 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
In interpreters which do not do a semantic-prepass, it is necessary
to fully macroexpand the body. Assuming the presence of a
SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
could look like:
(DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
(SETQ BINDINGS ;; Assure no non-atom bindings
(MAPCAR #'(LAMBDA (BINDING)
(IF (ATOM BINDING) (LIST BINDING) BINDING))
BINDINGS))
(PROGV (MAPCAR #'CAR BINDINGS)
(MAPCAR #'CDR BINDINGS)
(SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))
Modulo some bugs in the code. Shouldn't the second-to-last line be:
(MAPCAR #'(LAMBDA (BINDING)
(eval (CaDR BINDING)))
BINDINGS)
(my additions are in lowercase)?
barmar
∂13-Mar-89 1634 X3J13-mailer summary of active cl-compiler issues
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 16:34:43 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA11546; Mon, 13 Mar 89 17:32:30 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02645; Mon, 13 Mar 89 17:32:27 -0700
Date: Mon, 13 Mar 89 17:32:27 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903140032.AA02645@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: summary of active cl-compiler issues
Here is a list of all the active cl-compiler issues. Writeups for
all of these were mailed out earlier today.
CLOS-MACRO-COMPILATION (**DRAFT** version 2)
Clarify compile-time behavior of CLOS defining macros.
Proposal MINIMAL
Proposal NOT-SO-MINIMAL
(Still under active discussion.)
COMPILE-ENVIRONMENT-CONSISTENCY (version 4)
What kinds of things can/must the compiler "wire in" to the code
it compiles?
Proposal CLARIFY
COMPILE-FILE-SYMBOL-HANDLING (version 2)
How does COMPILE-FILE tell LOAD what package to put symbols in?
Proposal CURRENT-PACKAGE
Proposal HOME-PACKAGE
Proposal REQUIRE-CONSISTENCY
COMPILED-FUNCTION-REQUIREMENTS (version 4)
What does the COMPILED-FUNCTION type imply? Do COMPILE and
COMPILE-FILE construct COMPILED-FUNCTIONs?
Proposal TIGHTEN
Proposal TIGHTEN-COMPILE
COMPILER-DIAGNOSTICS (version 9)
Clarify status and handling of errors and warnings signalled during
compilation.
Proposal USE-HANDLER
COMPILER-LET-CONFUSION (version 7)
The description of COMPILER-LET in CLtL is broken -- should we fix
it or eliminate it entirely?
Proposal REPAIR
Proposal ELIMINATE
COMPILER-VERBOSITY (version 6)
Mechanisms for controlling progress messages issued by the compiler.
Proposal LIKE-LOAD
CONSTANT-CIRCULAR-COMPILATION (version 7)
Must circular or recursive objects be compiled correctly? Must the
compiler preserve sharing of substructures?
Proposal NO
Proposal PRESERVE-SHARING-ONLY
Proposal YES
(Expect amendment to change error terminology.)
CONSTANT-COLLAPSING (version 5)
Should the compiler be allowed to "collapse" or coalesce constants
that satisfy a more general equivalence relationship than EQUAL?
Proposal GENERALIZE
CONSTANT-COMPILABLE-TYPES (version 8)
What types of objects can appear as quoted or self-evaluating constants
in compiled code?
Proposal SPECIFY
(Expect amendments to change requirements for functions.)
DEFCONSTANT-NOT-WIRED (**DRAFT** version 6)
How do you delcare a variable to be constant without giving the
compiler permission to make assumptions about its value?
(None of the proposals are ready to be voted on. This issue
is being distributed only for informational purposes.)
DEFINE-OPTIMIZER (version 5)
Provide a macro-like way of specifying source-level optimizations
on function calls.
Proposal NEW-FACILITY
DEFINING-MACROS-NON-TOP-LEVEL (version 8)
Are defining macros such as DEFUN meaningful in non-top-level locations?
Proposal ALLOW
EVAL-WHEN-NON-TOP-LEVEL (version 6)
What does EVAL-WHEN mean when it appears in non-top-level locations?
Proposal GENERALIZE-EVAL
Proposal GENERALIZE-EVAL-NEW-KEYWORDS
LOAD-TIME-EVAL (version 11)
Add a new special form, LOAD-TIME-VALUE.
Proposal R**2-NEW-SPECIAL-FORM
Proposal R**3-NEW-SPECIAL-FORM
(Proposal R**2-NEW-SPECIAL-FORM was approved at the January meeting,
but some additional suggestions were made after the meeting.)
MACRO-CACHING (version 2)
Is it legitimate to cache macro expansions?
Proposal DISALLOW
Proposal RESTRICT
MACRO-ENVIRONMENT-EXTENT (**DRAFT** version 3)
Do environment objects received as the &ENVIRONMENT argument to a
macro have dynamic or indefinite extent?
Proposal INDEFINITE
Proposal DYNAMIC
Proposal DYNAMIC-WITH-COPIER
(Still under active discussion.)
PROCLAIM-ETC-IN-COMPILE-FILE (**DRAFT** version 4)
Are top-level calls to PROCLAIM handled specially by the compiler?
Proposal YES
Proposal NO
Proposal NEW-MACRO
(New rewrite.)
QUOTE-SEMANTICS (version 2) (replaces QUOTE-MAY-COPY)
May COMPILE and EVAL construct equivalent copies of quoted or
self-evaluating constants, or must constants share structure with
the source code for the program? Do the constraints on what objects
are valid constants also apply to COMPILE and EVAL, or only to
COMPILE-FILE?
Proposal NO-COPYING
Proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS
Proposal SAME-AS-COMPILE-FILE
SAFE-CODE (version 1)
What does the "safe code" mean?
Proposal SAFETY-3
SYNTACTIC-ENVIRONMENT-ACCESS (**DRAFT** version 4)
Provide accessors and constructors for lexical environment objects.
Proposal SMALL
Proposal MEDIUM
Proposal LARGE
(New rewrite.)
WITH-COMPILATION-UNIT (version 3)
Provide a way to compile a group of files as a unit for the purposes
of error messages.
Proposal NEW-MACRO
∂14-Mar-89 0938 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, version 7
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 09:37:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556615; Tue 14-Mar-89 12:35:04 EST
Date: Tue, 14 Mar 89 12:35 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-LET-CONFUSION, version 7
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132314.AA02546@defun.utah.edu>
Message-ID: <19890314173505.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
I generally favor the COMPILER-LET-CONFUSION:REPAIR proposal, however
I have a couple of comments and questions. Also of course I would want
to see the typo that BarMar found fixed.
What is the interaction between proposals COMPILER-LET-CONFUSION
and DEFINE-OPTIMIZER? Neither proposal says anything about that
as far as I can see. I believe the body of a optimizer must be
executed in the same dynamic environment as the body of a macro.
Cost to Implementors:
In interpreters which do not do a semantic-prepass, it is necessary
to fully macroexpand the body.
This is not true. A possible implementation technique for such
interpreters, in fact the one I would use, is to save the COMPILER-LET
bindings in a slot in the interpreter's lexical environment in the form
of an alist, and to make the MACROEXPAND-1 function bind those bindings
with PROGV around its call to the macroexpander. Using this technique
instead of fully macroexpanding the body deals with some of the
objections to the REPAIR proposal, I believe. Also promoting this
technique in the proposal would remove the need for the discussion
section to address the side-issue of whether code analyzing programs can
or cannot be written portably (an important issue in its own right, but
not part this one).
Current Practice:
Some implementations have implemented the description in CLtL.
Users of those implementations (quite reasonably) can't figure how to
use COMPILER-LET and so don't use it much.
Some implementations (the ones from which COMPILER-LET originally came)
continue to use their pre-CLtL semantics. These semantics are useful, though
incompatible with CLtL (which they largely consider to simply be in error).
Could you be more explicit about this? I was unable to figure out what you
are talking about, even after twice reading the introductory portion of the
proposal and the writeup in CLtL. I believe Symbolics Genera is one of those
implementations from which COMPILER-LET originally came and at the same time
implements COMPILER-LET exactly as CLtL specifies, so I must be missing some
important distinction. I'd like to see a precise description of these two
competing semantics and I'd also like to know which, if either, of them is
compatible with the REPAIR proposal.
∂14-Mar-89 0956 CL-Compiler-mailer issue DEFINE-OPTIMIZER, version 5
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 09:56:35 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556621; Tue 14-Mar-89 12:54:02 EST
Date: Tue, 14 Mar 89 12:54 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue DEFINE-OPTIMIZER, version 5
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132331.AA02562@defun.utah.edu>
Message-ID: <19890314175403.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
I generally like DEFINE-OPTIMIZER:NEW-FACILITY, but I would like
to suggest a couple of changes.
I'm not a fan of documentation strings, but shouldn't DEFINE-OPTIMIZER
allow them? Was their omission accidental or intentional?
Instead of returning two values from the body, I suggest returning one
value, or NIL to decline to optimize. If an optimizer wishes to
optimize into a form whose result is NIL, it should return (QUOTE NIL).
After all, if it wishes to optimize into a form whose result is FOO, it
has to return (QUOTE FOO), not FOO. The two values returned by
OPTIMIZE-EXPRESSION-1 are okay, since they are compatible with the two
values returned by MACROEXPAND-1. A reasonable alternative would be to
eliminate the two values at all levels, and also eliminate the special
casing of NIL, and simply specify that one declines to optimize by
returning the original form (compared with EQ). This will work but is
slightly more awkward for the optimizer writer, since &WHOLE would
have to be used. I'd accept this alternative if more people are in
favor of it, but I prefer special-casing NIL. I'd greatly prefer either
of those alternatives over what the proposal says now.
It isn't made clear whether OPTIMIZE-EXPRESSION returns one value
or two. It should be consistent with OPTIMIZE-EXPRESSION-1.
Using FLET and MACROLET shadow...
I assume it was only accidental that LABELS, GENERIC-LABELS, and
GENERIC-FLET were omitted from this list. I am unable to figure
out whether WITH-ADDED-METHODS should be included in this list
or not; I suspect not.
The similar Symbolics Genera facility allows more than one optimizer
to be defined for a given function; the optimizers are invoked in
unspecified order until one succeeds. This feature is actually
used, however I think it is okay to leave it out.
I agree with Barrett's comments quoted in the discussion section.
I'd like to see the proposal amended the way he suggests.
∂14-Mar-89 1005 CL-Compiler-mailer issue WITH-COMPILATION-UNIT, version 3
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 10:05:29 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556623; Tue 14-Mar-89 13:03:02 EST
Date: Tue, 14 Mar 89 13:03 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue WITH-COMPILATION-UNIT, version 3
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903140025.AA02634@defun.utah.edu>
Message-ID: <19890314180303.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
I oppose this because I don't think it's finished, however I expect I
would support it if it were finished. It may be that the amount of work
required to finish this is small and the proposal just needs amending.
I don't think it's acceptable to have something like this if its effect
is only defined for warnings, and its effect on compile-time
proclamations, compile-time macro definitions, compile-time defconstant
definitions, compile-time optimizer definitions, compile-time type
definitions, compile-time setf definitions, and compile-time CLOS
definitions is left unspecified.
I think lumping COMPILE and COMPILE-FILE together here reflects
confusion. COMPILE and COMPILE-FILE have very little to do with each
other, and I think it's clear that COMPILE should not be affected in any
way by WITH-COMPILATION-UNIT. Having COMPILE affected by
WITH-COMPILATION-UNIT is as unreasonable as having MACROEXPAND affected
by WITH-COMPILATION-UNIT, if you ask me. I think removing COMPILE would
address Barrett's complaint in the discussion section; that is, I think
having COMPILE-FILE not override an enclosing WITH-COMPILATION-UNIT is
correct.
∂14-Mar-89 1217 CL-Compiler-mailer **DRAFT** issue MACRO-ENVIRONMENT-EXTENT, version 3
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 12:17:12 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556715; Tue 14-Mar-89 15:09:52 EST
Date: Tue, 14 Mar 89 15:09 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue MACRO-ENVIRONMENT-EXTENT, version 3
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132355.AA02585@defun.utah.edu>
Message-ID: <19890314200952.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
I strongly favor MACRO-ENVIRONMENT-EXTENT:DYNAMIC over any of the other four.
∂14-Mar-89 1232 CL-Compiler-mailer **DRAFT** issue PROCLAIM-ETC-IN-COMPILE-FILE (version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 12:32:34 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556743; Tue 14-Mar-89 15:29:24 EST
Date: Tue, 14 Mar 89 15:29 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue PROCLAIM-ETC-IN-COMPILE-FILE (version 4)
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903140008.AA02608@defun.utah.edu>
Message-ID: <19890314202917.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
I favor PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO, primarily because this
allows programs to be clear about the scope of the proclamation:
whether they are making a proclamation for purposes of compile-file or
to affect the running Lisp. If you call the macro at top-level, you're
clearly doing it for compilation. If you call the function at any level,
you're clearly doing it with global scope.
In PROCLAIM-ETC-IN-COMPILE-FILE:NO there is no way to say whether a
PROCLAIM inside an (EVAL-WHEN (COMPILE...) ...) is intended to persist
after the compilation is over, which is just about the only reason
why I prefer PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO over :NO.
I'd like PROCLAIM-ETC-IN-COMPILE-FILE:NO better if it also proposed
to add an optional argument to PROCLAIM that expressed the intended
scope of the proclamation. I'd suggest NIL (the default) for the
global scope and the symbol COMPILE-FILE to limit it to the compilation.
Given this, users who liked DEFPROCLAIM could trivially write it
themselves.
The only thing PROCLAIM-ETC-IN-COMPILE-FILE:YES has going for it is
that it's the status quo, in a subset of implementations. I don't like it.
I agree with Barrett's comments quoted in the discussion section.
The proposal says:
As with other defining macros, it is
unspecified whether or not the compile-time side-effects of a
DEFPROCLAIM persist after the file has been compiled.
but never says this about PROCLAIM. In all three proposals,
this needs to be said about PROCLAIM. But as you can see from my
comments above, I would rather that we did not leave this unspecified.
The proposal says:
Current Practice:
The Symbolics compiler has special top-level handling for PROCLAIM,
although the details are not clear.
I'm not sure what you thought was not clear. Symbolics Genera does the
same thing that the current practice section says IIM does. In addition
(and I couldn't tell whether IIM does this too or not), the scope of the
PROCLAIM is only the compilation-unit if the PROCLAIM appears at
top-level, but is global and persists forever if the PROCLAIM appears in
an (EVAL-WHEN (COMPILE...) ...). We might change that.
∂14-Mar-89 1310 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 8
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 13:09:32 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556774; Tue 14-Mar-89 15:58:28 EST
Date: Tue, 14 Mar 89 15:58 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 8
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132333.AA02565@defun.utah.edu>
Message-ID: <19890314205826.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
I favor DEFINING-MACROS-NON-TOP-LEVEL:ALLOW except for one thing.
This sentence appears in the proposal but does not appear to have
any relation to the main issue:
The order in which
non-top-level subforms of a top-level form are processed by the
compiler is explicitly left unspecified.
I can't figure out what this means and the example in the rationale
section that purports to explain this does not shed any light, since in
the example there is no change of order of evaluation. I wouldn't be
surprised if I opposed this if I did understand what it means. Can we
deal with this as a separate issue? In fact the whole point (3) of the
proposal should be moved. That issue should also discuss whether there
are any constraints on whether one top-level form is processed before
the next top-level form is read, in case the one form changes package,
changes readtable, defines a read-syntax, or defines a structure used in
#S read-syntax.
Also, when you say:
Clarify
that all defining macros which create functional objects (including
DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
DEFSETF, as well as DEFUN) must ensure that those functions are
defined in the lexical environment in which the defining form is
evaluated.
I strongly believe that MACROLET must be consistent with this, which
would be a change. Has that been dealt with as a separate issue? If
not, it should either be added to this issue or brought up as a
separate issue, with the interdependency noted in both writeups to
minimize the chance of an inconsistent vote.
∂14-Mar-89 1326 CL-Compiler-mailer issue COMPILE-FILE-SYMBOL-HANDLING, version 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 13:25:58 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556792; Tue 14-Mar-89 16:23:12 EST
Date: Tue, 14 Mar 89 16:23 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILE-FILE-SYMBOL-HANDLING, version 2
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132312.AA02542@defun.utah.edu>
Message-ID: <19890314212313.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
I favor COMPILE-FILE-SYMBOL-HANDLING:CURRENT-PACKAGE.
COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE seems superficially simpler,
but my experience when we tried it at MIT indicates that it does not
work very well. Too often a symbol that had been moved from one package
to another, or had its export status changed, would be silently moved
back to its original package by loading a file. I sort-of agree with
JonL's comment at the end of the discussion section: if we can't agree
on one solution to his issue, I think that in practice there would be
little harm to portable programs if we left it unspecified. The issue
really affects development environments much more than it affects the
language in which portable programs are written, although it does have
some effect on that as well.
∂14-Mar-89 1340 CL-Compiler-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 13:40:33 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 556802; 14 Mar 89 16:37:50 EST
Date: Tue, 14 Mar 89 16:37 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132250.AA02499@defun.utah.edu>
Message-ID: <19890314213750.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
All the things I didn't like in version 3 have been fixed.
I would favor COMPILE-ENVIRONMENT-CONSISTENCY:CLARIFY if one change
were made. The proposal says:
Except where some other behavior is explicitly stated, when
the compiletime and runtime definitions are different, it is
unspecified which will prevail within the compiled code.
This means that either the compiletime or the runtime definition
will prevail, but nothing else can happen. It must also be
permissible to signal an error complaining about the discrepancy.
∂14-Mar-89 1351 CL-Compiler-mailer issue SAFE-CODE, version 1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 13:51:31 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556829; Tue 14-Mar-89 16:49:05 EST
Date: Tue, 14 Mar 89 16:49 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue SAFE-CODE, version 1
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131726.AA02193@defun.utah.edu>
Message-ID: <19890314214907.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
I agree with SAFE-CODE:SAFETY-3.
I disagree with the usage (in the examples) of "unsafe code" to mean
"all code where the OPTIMIZE quality of SAFETY is not 3." I believe
that "unsafe code" should mean code that is actually unsafe, not code
that an implementation is permitted to treat as unsafe if it wishes. I
believe there should be no portable way to write unsafe code. This is
only a matter of wording. If we need a shorter term for "all code where
the OPTIMIZE quality of SAFETY is not 3" I would suggest "potentially
unsafe code."
∂14-Mar-89 1357 CL-Compiler-mailer issue COMPILER-VERBOSITY, version 6
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 13:56:56 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556842; Tue 14-Mar-89 16:54:22 EST
Date: Tue, 14 Mar 89 16:54 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-VERBOSITY, version 6
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131546.AA02078@defun.utah.edu>
Message-ID: <19890314215423.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
I like COMPILER-VERBOSITY:LIKE-LOAD. This fixes all of the
problems I had with the version 5 proposal.
Like BarMar, I question the need for either of :PRINT and :VERBOSE in
either of LOAD and COMPILE-FILE. But that might be my own cultural
bias, due to the type of systems I use, where it's easy to see what's
going on inside. If other people claim they need these, I'll believe
them.
∂14-Mar-89 1419 X3J13-mailer Issue: ERROR-NOT-HANDLED (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Mar 89 14:19:42 PST
Received: from Semillon.ms by ArpaGateway.ms ; 14 MAR 89 14:03:50 PST
Date: 14 Mar 89 14:02 PST
From: masinter.pa@Xerox.COM
to: X3J13@sail.stanford.edu
Subject: Issue: ERROR-NOT-HANDLED (Version 1)
reply-to: cl-cleanup@sail.stanford.edu
line-fold: NO
Message-ID: <890314-140350-1917@Xerox>
Cleanup issues for the next meeting will be tricking out over the next
week.
This issue was distributed prior to the October 1988 meeting,
but not voted on.
!
Issue: ERROR-NOT-HANDLED
References: Interactive Condition Handling (Condition System, Rev 18, p19)
Category: CLARIFICATION/CHANGE
Edit history: 25-Sep-88, Version 1 by Pitman
Problem Description:
For delivery purposes, some implementations will want to leave out
major sections of runtime support in programs that do not require
them. The debugger is one such section.
However, since ERROR may be called implicitly by a number of Common
Lisp built-in functions, and since the condition system as currently
described insists that the interactive debugger be entered if a
condition is unhandled, the interactive debugger must be retained in
a saved image of any program that might signal an error unless the
compiler can prove that the error will never go unhandled. This
may be undesirable in some cases and may cause unnecessary bloating
of the saved image.
Proposal (ERROR-NOT-HANDLED:PERMIT-TERMINATION):
Permit implementors to designate an implementation-specific mechanism
for asking that unhandled errors cause `termination of the running
program' rather than entry into the system's debugger.
Implementations choosing to offer such a facility must clearly define
the nature and scope of such program termination, since the concept
of `program termination' is an ill-defined concept in present-day
Common Lisp.
Even when program termination rather than debugger entry would be
the ultimate effect of an unhandled error, the value of
*DEBUGGER-HOOK* (if non-NIL) must be called to provide programmers
the ability of customized debugging.
All implementations must at least provide the option of a system
debugger for use in program development.
Test Case:
(ERROR "Foo"), if unhandled, must now enter the debugger.
Under this proposal, it might also `terminate program execution'
in implementations which choose to provide such a facility and to
clearly define that concept.
Rationale:
Although technically an incompatible change, we're dealing at
the very edge of what the user can expect from the system. Once
an error is signalled and not handled, we're in the domain of
implementation-dependent effect anyway.
Current Practice:
Probably no one does this yet.
Cost to Implementors:
None. This change is upward compatible with existing implementations.
Cost to Users:
None.
Cost of Non-Adoption:
Saved Lisp images might be forced to be gratuitously larger than
they need to be in some implementations.
Benefits:
Addressing this issue will make Lisp more able to compete with
other languages which permit small saved images to result from
small user programs.
Aesthetics:
No significant impact.
Discussion:
This change was requested by Christian Queinnec of France
(queinnec@inria.inria.fr). Pitman supports the change.
∂14-Mar-89 1438 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 9
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 14:38:21 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556909; Tue 14-Mar-89 17:35:56 EST
Date: Tue, 14 Mar 89 17:35 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-DIAGNOSTICS, version 9
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131545.AA02075@defun.utah.edu>
Message-ID: <19890314223550.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
I favor COMPILER-DIAGNOSTICS:USE-HANDLER, but there are two
things that I think need to be changed:
Conditions of type WARNING may be signalled by the compiler in
situations where ... the compiler can determine
that a situation that "is an error" would result at runtime.
We don't use the term "is an error" any more, do we? In the old
CLtL terms, I think both "is an error" and "signals an error"
situations would justify a warning. I think this part should
be updated to the new error terminology and also should state that
all error situations justify warnings. Of course explicit calls
to the function ERROR don't justify warnings; I don't know whether
the proposal can be phrased in such a way as to make that clear,
or whether it will have to be left to common sense.
(3) Require COMPILE and COMPILE-FILE to handle the ABORT restart by
aborting the smallest feasible part of the compilation.
I think this is wrong. The only documentation of the ABORT restart
that I could find says
The purpose of the ABORT restart is generally to allow return to the
innermost ``command level.''
I agree with this, and I believe it means that it is wrong for any
function other than one that establishes a read-eval-print loop or
a command-level to establish an ABORT restart. It would be useful
to have some restart that aborts a portion of the compilation, but
it should be given some other name.
∂14-Mar-89 1505 CL-Cleanup-mailer Issue: ERROR-NOT-HANDLED (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 15:04:58 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556941; Tue 14-Mar-89 18:02:30 EST
Date: Tue, 14 Mar 89 18:02 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ERROR-NOT-HANDLED (Version 1)
To: cl-cleanup@sail.stanford.edu
cc: X3J13@sail.stanford.edu
In-Reply-To: <890314-140350-1917@Xerox>
Message-ID: <19890314230224.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
ERROR-NOT-HANDLED:PERMIT-TERMINATION is okay with me. I would
also support a proposal to replace "the condition system as currently
described insists that the interactive debugger be entered if a
condition is unhandled" with wording that allowed implementations
to do whatever they want, with perhaps an implementation note that
many implementations prefer an interactive debugger.
∂14-Mar-89 1544 CL-Compiler-mailer **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
Received: from YUKON.SCRC.Symbolics.COM (SCRC-YUKON.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 15:44:06 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 438041; Tue 14-Mar-89 18:42:58 EST
Date: Tue, 14 Mar 89 18:41 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903140019.AA02631@defun.utah.edu>
Message-ID: <19890314234118.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
This looks good so far. A few comments that might help you
along with the draft:
VARIABLE-KIND should return the same second value that FUNCTION-KIND
returns.
It's a good idea to avoid the ambiguous word "may" and say "might",
"must", or "is permitted to".
I would assume that VARIABLE-TYPE is not required to return the
exact declared type specifier, but could return another type
specifier that is equivalent, or possibly another type specifier
that is a supertype. An implementation that canonicalizes type
declarations would do this. For example, if A was declared
(INTEGER 0 4999), VARIABLE-TYPE might return that list, another
list that was EQUAL to it but not EQ, the list (INTEGER (-1) (5000)),
the symbol FIXNUM, or perhaps something else. Similarly OR's and
AND's might be reduced to simpler type specifiers in an implementation
dependent way. If, on the other hand, VARIABLE-TYPE is not permitted
to do this, but must return the exact type specifier used in the
declaration, that would be okay, but should be stated explicitly.
Similar comments apply to FUNCTION-FTYPE of course.
I assume AUGMENT-ENVIRONMENT is permitted to share structure with
its env argument, although the proposal says "a copy of ENV".
The :MACRO argument to AUGMENT-ENVIRONMENT shouldn't look like the CADR
of a MACROLET special form, instead it should be a list of lists (name
function). That is, the expander functions should be supplied in the
form of functions rather than in the form of the source text used by
MACROLET. Your rationale argues against this but I strongly believe
that the rationale is wrong. I wouldn't mind seeing the parsing portion
of MACROLET made available as a separate function.
No way is provided to retrieve declarations other than SPECIAL, TYPE,
FTYPE, and LEXICAL (if PROCLAIM-LEXICAL passes). I think all
declarations should be retrievable, but OPTIMIZE declarations seem
particularly useful to retrieve in macros or optimizers that expand into
different code depending on the safety level or the speed/space
tradeoff. The irregular structure of declarations makes retrieving
them a bit complex, but here's my suggestion:
DECLARATION decl-type name &optional env [Function]
decl-type is a symbol. The interpretation of name depends
on decl-type. If a declaration of that type and name is
in force in the specified environment, it is returned, otherwise
NIL is returned. The following decl-types are specified,
additional implementation-dependent types could be added:
INLINE function-name => T or NIL
NOTINLINE function-name => T or NIL
IGNORE variable-name => T or NIL
OPTIMIZE quality => integer
DECLARATION decl-type => T or NIL
The possible interpreter implementation of COMPILER-LET I mentioned
in another message earlier today would seem to require another
keyword argument to AUGMENT-ENVIRONMENT. Does this mean that we
have to dictate some particular interpreter implementation of
COMPILER-LET? I'm unsure.
Symbolics Genera includes an undocumented internal macro, used
quite a bit in the implementation of the interpreter and code
analyzers, that could have been called WITH-AUGMENTED-ENVIRONMENT,
taking keywords like AUGMENT-ENVIRONMENT and also body forms,
and producing an environment with dynamic extent bound to a
variable within the body forms. Would it be useful to have this
too, or instead of AUGMENT-ENVIRONMENT? I'm unsure.
On SYNTACTIC-ENVIRONMENT-ACCESS:MEDIUM, my feeling today is that
this should be left out for now, even though I think we will want
something like it later, at the same time that CLOS metaobjects
go in.
Ditto for SYNTACTIC-ENVIRONMENT-ACCESS:LARGE.
∂14-Mar-89 1555 X3J13-mailer LETTER BALLOT -- Sun Microsystems
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 14 Mar 89 15:55:09 PST
Received: from snail.Sun.COM (snail.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.0)
id AA21551; Tue, 14 Mar 89 15:16:32 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA11449; Tue, 14 Mar 89 15:12:40 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA26931; Tue, 14 Mar 89 15:16:13 PST
Date: Tue, 14 Mar 89 15:16:13 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903142316.AA26931@clam.sun.com>
To: chapman%aitg.DEC@decwrl.dec.com
Subject: LETTER BALLOT -- Sun Microsystems
Cc: kempf%clam@Sun.COM, peck%clam@Sun.COM, sgadol%clam@Sun.COM,
x3j13@sail.stanford.edu
This is the Sun Microsystems vote.
________________________________________________________________________
Issue or section name | Version | Y | I | A |
------------------------------------------------------------------------
CUT-OFF-DATES | 4 | | I | |
------------------------------------------------------------------------
ERROR-TERMINOLOGY | 5 | | I | |
------------------------------------------------------------------------
FONTS | 2 | Y | | |
------------------------------------------------------------------------
TOC | 1 | Y | | |
------------------------------------------------------------------------
Section 1.8 | 5.8 | Y | | |
------------------------------------------------------------------------
Section 2.3 | 5.8 | Y | | |
------------------------------------------------------------------------
Section 2.4 | 5.8 | Y | | |
------------------------------------------------------------------------
Section 2.5 | 5.8 | | | A |
------------------------------------------------------------------------
Section 6.1 | 5.8 | | I | |
------------------------------------------------------------------------
Overall, I'm impressed with the work that has been done on
writing the standard, but not entirely comfortable with the process
I can see for getting from where we are to an actual standard.
CUT-OFF-DATES
I have both general and specific comments about the CUT-OFF-DATES
proposal. The general comments first:
The cutoff dates question causes me some discomfort, and I think
that is because the proposal is not as explicit as it might be.
First, how about stating what the goal for 12/89 is? E.g. a
draft standard approved by X3J13 and ready for release and
outside comments.
Second, as I understand it, the "final changes" dates are for
final changes from the selected reviewers for each section of
the standard, though this is not stated.
The process, as I understand it, is that a set of reviewers will
read each section (or set of tool descriptions) carefully and
submit corrections, etc.. The full committee will then vote on
these.
A proper review will need to be done by subject rather than by sections
of the alphabet. In fact at least one person at Sun has volunteered to
work on a particular subject. Note that Moon expects Symbolics
internal reviewers to do likewise. To me that implies the catalog of
tools must be voted on by subject rather than alphabetically, so I
recommend reorganizing those cutoff dates and votes by subject.
Moon suggests that it will take "several months" for Symbolics
to review the draft standard, and that the availability of
the cleanup process will be important for fixing problems
in the statement of the draft standard. I second this.
Being active in the compiler committee, I feel confident that a
well-constructed section on compilation will *not* be ready by
4/22/89. We need to bring the compiler work to a conclusion as close
to that date as we can, though, even if all is not perfect. The full
committee needs to help make this happen. (Thanks especially to David
Moon for his recent input.)
ERROR-TERMINOLOGY
The error terminology is OK, except for "consequences
are unspecified". That concept is broken, though it
has serious defenders. For example, Dick Gabriel says,
"If we were to drop this term, then every time we are
``explicitly vague'' a valid possibility is that a fatal
error can occur. How is it any better to say that what happens
when some operation happens is ``explicitly vague''."
A typical area of "explicit vagueness" is the destructive operations
on lists. The explicit vagueness here is quite limited. For
some operations any top level cell of certain lists may or may
not be modified. Similar statements apply to other operations.
The consequences are far from being unspecified but harmless.
They are CONSTRAINED but meaningful.
In other situations we may say that order of certain actions
is unspecified or we may say that a side effect may or may not
occur. (For example, numerical operations may be performed
in any of various orders.) All of these are appropriate ways
to state a specification.
Maybe someone will make me suddenly see the light and I'll realize
how silly I've been, but so far the idea of consequences being
"unspecified but harmless" seems more like a witticism than
a useable idea.
SECTION 6.1
Under "Other Information", many of the terms are actually
type specifiers. Wouldn't it be better to say that if a name
is the same as a type specifier, that argument must satisfy
the type specifier?
arguments to the function -- unclear to me
boolean -- I presume this are to be arguments where
all non-NIL values are *treated* alike.
Note that for macros we truly specify *syntax* (at least
for some, e.g. defstruct. For most functions we actually
give a lambda list.
p6-8, item 2b, the keyword :test-not has been flushed from
the sequence functions.
∂14-Mar-89 1610 X3J13-mailer Re: Issue: UNSOLICITED-MESSAGES
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 14 Mar 89 16:09:57 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa07509; 14 Mar 89 18:01 GMT
Date: Tue, 14 Mar 89 17:58:24 GMT
Message-Id: <8289.8903141758@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue: UNSOLICITED-MESSAGES
To: Kent M Pitman <KMP@scrc-stony-brook.arpa>, barmar@think.com
Cc: chapman <@decwrl.dec.com:chapman@aitg.dec>, x3j13@sail.stanford.edu
> Why is this problem unique to Lisp? Is there any wording in the C
> standard that explicitly prohibits malloc() from causing output? I
> doubt it, yet I don't think they find this disturbing.
>
> Maybe it's because C people have traditionally been willing to settle
> for less. :-) Seriously, I think it's a clear hole in their standard.
> People would probably flame if things that weren't documented as doing
> I/O were to suddenly start doing it.
As far as I know, the C standard also doesn't say that assignment
doesn't print out "I'm doing an assignment" or, indeed, that y = 6
doesn't also assign 17 to xyzzy. But does it need to make explicit
prohibitions?
The C standard says "In the abstract machine, all expressions are
evaluated as specified by the semantics." Presumably there is an
implication that it doesn't do random other things.
-- Jeff
∂14-Mar-89 1629 CL-Compiler-mailer issue CONSTANT-COMPILABLE-TYPES, version 8
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 16:29:32 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557038; Tue 14-Mar-89 19:27:03 EST
Date: Tue, 14 Mar 89 19:27 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CONSTANT-COMPILABLE-TYPES, version 8
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131612.AA02083@defun.utah.edu>
Message-ID: <19890315002703.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
I apologize in advance for the length of this message.
This is good except for a few typos and the controversial business about
functions. I'd really like to see another round of editing to clean up
these problems before we're asked to vote on this.
I suggest moving everything having to do with functions to a
separate proposal. What's currently in the body of the proposal for
functions does not make any sense to me. I basically agree with the
comments from both Loosemore and Gabriel about this quoted in the
discussion section. However, we need to be careful when we discuss this
to distinguish between a function as a constant in compiled code, and a
form whose result is a function appearing in compiled code. The former
is `(quote ,#'(lambda ...)), the latter is `#'(lambda ...). The meaning
of the latter is clear, of course, and a useful question would be
whether it can fully satisfy the need for functions in compiled code and
eliminate any demand for the former.
I've said this before, but I still think the proposal would be
easier to understand if it explicitly dealt separately with
(1) relation of objects in the input of COMPILE-FILE to corresponding
objects in the result of LOAD of the output of COMPILE-FILE.
(2) relation of two objects in the output of a single COMPILE-FILE.
(3) relation of two objects in the output of two different COMPILE-FILEs.
instead of smushing these together in a fuzzy way. Look at the discussion
of uninterned symbols, for example: I found it incomprehensible.
Typos:
For any object that
appears in a constant, but is not supported by the language as part of
a constant, the behavior of the compiler is unspecified; either the
the compiler and/or loader will handle that constant (in an
implementation-dependent manner) or the compiler will detect the
situation and signal an error.
This says that the behavior of the compiler is unspecified and then
proceeds to specify it!
Because hash keys can be aggregate objects and because we treat hash
tables as unordered sets of <key, value> pairs, similarity of hash
tables is more complex. See under "Hash Tables", below, for the
definition.
I have no idea how this paragraph got into the middle of the discussion
of uninterned symbols.
References to packages are permitted in any constant.
This sentence is redundant, or else it implies that references to some
other types are permitted in some constants but not in other constants,
which I don't think you intended.
At load time, the package becomes the same as returned by
I don't know what it means for a package to "become". I think
this is just fractured syntax, though. See again my suggestion
for distinguishing the three types of similarity, which I think
indicates how to rewrite this sentence to be clear.
Under hash table:
The table's test is unchanged also.
Unchanged from what? I think what this was supposed to say was
that the table's test is a "basic attribute."
Consider a hash table as an unordered set of key and
value pairs. Two hash tables are similar as constants
exactly if there is a one-to-one correspondence between
the key and value pairs of each and a one-to-one
correspondence between the uninterned symbols of each
such that the two keys of each corresponding pair are
similar as constants and the two values are also similar
as constants. The correspondence of uninterned symbols
must be consistent with the correspondence defined for
the entire set of constants in the file.
This paragraph is totally garbled. If you took out the
stuff about uninterned symbols it might make sense.
Structure, Standard-object
<<There is a cl-cleanup issue, LOAD-OBJECTS, pending
which proposes a mechanism for dealing with objects.>>
For structure instances with no method defined at compile
time for MAKE-LOAD-FORM, the slot values and the name of
structure type (a symbol reference) are recorded by the
compiler and reconstructed by the loader.
The text not enclosed in french quotation marks directly contradicts
the LOAD-OBJECTS proposal. It should be removed so we don't have two
proposals trying to talk about the same thing.
This sentence in the discussion section:
The full extension of the concept of coalescing of constants is to say
that they can be coalesced exactly when they are similar as constants.
seems to be in the wrong document, since this issue is not about
coalescing of constants and does not otherwise mention it, except
incidentally in connection with a bug in Coral Lisp.
∂14-Mar-89 1636 CL-Compiler-mailer issue CONSTANT-COMPILABLE-TYPES, version 8
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 16:36:44 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557048; Tue 14-Mar-89 19:34:07 EST
Date: Tue, 14 Mar 89 19:34 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CONSTANT-COMPILABLE-TYPES, version 8
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131612.AA02083@defun.utah.edu>
Supersedes: <19890315002703.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: Fix some typos in the definitions of the three concepts that I claim
should not be smushed together. Cris Perdue pointed out these typos
earlier, but I forgot to fix them before sending the first copy of this
message.
Message-ID: <19890315003408.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
I apologize in advance for the length of this message.
This is good except for a few typos and the controversial business about
functions. I'd really like to see another round of editing to clean up
these problems before we're asked to vote on this.
I suggest moving everything having to do with functions to a
separate proposal. What's currently in the body of the proposal for
functions does not make any sense to me. I basically agree with the
comments from both Loosemore and Gabriel about this quoted in the
discussion section. However, we need to be careful when we discuss this
to distinguish between a function as a constant in compiled code, and a
form whose result is a function appearing in compiled code. The former
is `(quote ,#'(lambda ...)), the latter is `#'(lambda ...). The meaning
of the latter is clear, of course, and a useful question would be
whether it can fully satisfy the need for functions in compiled code and
eliminate any demand for the former.
I've said this before, but I still think the proposal would be
easier to understand if it explicitly dealt separately with
(1) relation of objects in the input of COMPILE-FILE to corresponding
objects in the result of LOAD of the output of COMPILE-FILE.
(2) relation of two objects in the result of LOAD of the output
of a single COMPILE-FILE.
(3) relation of two objects in the result of LOAD of the output
of two different COMPILE-FILEs.
instead of smushing these together in a fuzzy way. Look at the discussion
of uninterned symbols, for example: I found it incomprehensible.
Typos:
For any object that
appears in a constant, but is not supported by the language as part of
a constant, the behavior of the compiler is unspecified; either the
the compiler and/or loader will handle that constant (in an
implementation-dependent manner) or the compiler will detect the
situation and signal an error.
This says that the behavior of the compiler is unspecified and then
proceeds to specify it!
Because hash keys can be aggregate objects and because we treat hash
tables as unordered sets of <key, value> pairs, similarity of hash
tables is more complex. See under "Hash Tables", below, for the
definition.
I have no idea how this paragraph got into the middle of the discussion
of uninterned symbols.
References to packages are permitted in any constant.
This sentence is redundant, or else it implies that references to some
other types are permitted in some constants but not in other constants,
which I don't think you intended.
At load time, the package becomes the same as returned by
I don't know what it means for a package to "become". I think
this is just fractured syntax, though. See again my suggestion
for distinguishing the three types of similarity, which I think
indicates how to rewrite this sentence to be clear.
Under hash table:
The table's test is unchanged also.
Unchanged from what? I think what this was supposed to say was
that the table's test is a "basic attribute."
Consider a hash table as an unordered set of key and
value pairs. Two hash tables are similar as constants
exactly if there is a one-to-one correspondence between
the key and value pairs of each and a one-to-one
correspondence between the uninterned symbols of each
such that the two keys of each corresponding pair are
similar as constants and the two values are also similar
as constants. The correspondence of uninterned symbols
must be consistent with the correspondence defined for
the entire set of constants in the file.
This paragraph is totally garbled. If you took out the
stuff about uninterned symbols it might make sense.
Structure, Standard-object
<<There is a cl-cleanup issue, LOAD-OBJECTS, pending
which proposes a mechanism for dealing with objects.>>
For structure instances with no method defined at compile
time for MAKE-LOAD-FORM, the slot values and the name of
structure type (a symbol reference) are recorded by the
compiler and reconstructed by the loader.
The text not enclosed in french quotation marks directly contradicts
the LOAD-OBJECTS proposal. It should be removed so we don't have two
proposals trying to talk about the same thing.
This sentence in the discussion section:
The full extension of the concept of coalescing of constants is to say
that they can be coalesced exactly when they are similar as constants.
seems to be in the wrong document, since this issue is not about
coalescing of constants and does not otherwise mention it, except
incidentally in connection with a bug in Coral Lisp.
∂14-Mar-89 1651 CL-Compiler-mailer issue QUOTE-SEMANTICS, version 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 16:51:17 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557056; Tue 14-Mar-89 19:48:51 EST
Date: Tue, 14 Mar 89 19:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue QUOTE-SEMANTICS, version 2
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131721.AA02184@defun.utah.edu>
Message-ID: <19890315004852.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
I favor QUOTE-SEMANTICS:NO-COPYING for two reasons:
(1) it's clearly more aesthetic.
(2) I can't support either of the other two proposals because they use
the words "copying" and "coalescing" without defining their meaning.
My position could be changed to
QUOTE-SEMANTICS:COPYING-ALLOWED-BUT-NO-CONSTRAINTS by adding definitions
for those two words and by a strong argument that the implementation
cost of QUOTE-SEMANTICS:NO-COPYING is too high, since I believe to some
extent JonL's argument (quoted in the discussion section) that EQL of
(some types of) constants does not matter.
I can't imagine any argument that would convince me to
support QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE. I believe Kent's
arguments against it (quoted in the discussion section).
∂14-Mar-89 1700 CL-Compiler-mailer issue MACRO-CACHING, version 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 17:00:30 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557059; Tue 14-Mar-89 19:57:55 EST
Date: Tue, 14 Mar 89 19:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue MACRO-CACHING, version 2
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131647.AA02151@defun.utah.edu>
Message-ID: <19890315005756.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
I support MACRO-CACHING:DISALLOW. I'd like to point out that the
"correct" way to do macro caching is not mentioned anywhere in this
writeup. Perhaps that was justified because there is no portable way to
do it (an implementation can do it, but a user cannot), however I think
omitting it leaves a false impression.
The "correct" way to do macro caching is via a table inside the lexical
environment structure, which has very different properties from a table
keyed by the lexical environment structure, mentioned in the writeup.
I think a shorter writeup might be better. It could simply say that
there is no correct portable way to use *MACROEXPANSION-HOOK* to cache
macro expansions, and that there is no requirement that an implementation
call the macro expansion function more than once for a given form
and lexical environment. This prohibits the incorrect user code discussed
at some length in the existing writeup, leaves implementations license
to do macro caching correctly, and avoids a lot of unnecessary detail.
∂14-Mar-89 1704 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 11
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 17:04:49 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 557069; 14 Mar 89 20:02:04 EST
Date: Tue, 14 Mar 89 20:02 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue LOAD-TIME-EVAL, version 11
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131631.AA02140@defun.utah.edu>
Message-ID: <19890315010205.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
I like LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM.
∂14-Mar-89 1722 CL-Compiler-mailer issue CONSTANT-COLLAPSING, version 5
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 17:21:52 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557083; Tue 14-Mar-89 20:10:42 EST
Date: Tue, 14 Mar 89 20:10 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CONSTANT-COLLAPSING, version 5
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131622.AA02093@defun.utah.edu>
Message-ID: <19890315011043.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
The proposal says:
State the an implementation is permitted to coalesce constants
appearing in code to be compiled if they are equivalent under the
relationship defined in proposal CONSTANT-COMPILABLE-TYPES:SPECIFY.
I can't understand what this means. The referenced proposal uses
the word "similar", not "equivalent". I'd support this alternate
wording:
Suppose that A and B are two objects used as quoted constants in the
input to COMPILE-FILE, and that A' and B' are the corresponding
objects used as constants in the result of loading the output of
that COMPILE-FILE. If A' is similar as a constant to both A and B,
then it is valid for A' and B' to be EQL even if A and B are not EQL.
This may still be too vague, since "objects in the input to
COMPILE-FILE" means not in the input text file, which doesn't contain
objects, but in the result of applying READ to the input file, and since
"corresponding objects" is not defined.
∂14-Mar-89 1722 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 7
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 17:21:59 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557096; Tue 14-Mar-89 20:15:39 EST
Date: Tue, 14 Mar 89 20:15 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 7
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131619.AA02090@defun.utah.edu>
Message-ID: <19890315011539.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
I favor CONSTANT-CIRCULAR-COMPILATION:YES except that all references to
EQ should be changed to EQL. There is no reason to require
implementations to be careful about EQ of numbers and characters.
∂14-Mar-89 1731 X3J13-mailer Issue: GENSYM-NAME-STICKINESS (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Mar 89 17:31:12 PST
Received: from Semillon.ms by ArpaGateway.ms ; 14 MAR 89 14:57:16 PST
Date: 14 Mar 89 14:56 PST
From: masinter.pa@Xerox.COM
Subject: Issue: GENSYM-NAME-STICKINESS (Version 1)
To: x3j13@SAIL.Stanford.EDU
reply-to: cl-cleanup@sail.stanford.edu
line-fold: no
Message-ID: <890314-145716-2049@Xerox>
Additional Comments include:
"... it's ... late to consider things like this ..."
"YAY!!! This is what "cleanup" is for. Go For It! "
"Sounds like a good idea to me."
!
Issue: GENSYM-NAME-STICKINESS
Forum: Cleanup
References: GENSYM (p169)
Category: CHANGE
Edit history: 14-Feb-89, Version 1 by Pitman
Problem Description:
Many people avoid use of the argument to GENSYM because the argument
is `sticky' and such stickiness can lead to confusion. The problem is
that if any application (usually a macro) uses the gensym argument at
all, then all applications are forced to. If they do not, they risk
finding that the `helpful' argument supplied in some previous call will
be harmful to them.
Proposal (GENSYM-NAME-STICKINESS:WASH-HANDS):
Define that if an optional argument is given to GENSYM, it does NOT
have a side-effect on GENSYM's internal state.
Rationale:
Conscientious programmers are forced now to write their own GENSYM
lookalikes because they know the system's GENSYM has an invasive
effect. This defeats the primary intended function of GENSYM, which
is to satisfy the most common idiomatic use of MAKE-SYMBOL.
The stickiness of the GENSYM prefix was an attempt to be gratuitously
compatible with Maclisp, at the expense of good programming pratice.
Users who need the old behavior of GENSYM can trivially implement
that behavior using MAKE-SYMBOL.
Test Case:
(CHAR-EQUAL (CHAR (SYMBOL-NAME (SECOND (LIST (GENSYM "A") (GENSYM)))) 0)
#\G)
=> NIL ;under CLtL
=> T ;under this proposal
Current Practice:
Symbolics Cloe and Genera are compatible with CLtL, so this would be an
incompatible change.
Cost to Implementors:
Very small.
Cost to Users:
Most uses of GENSYM do not depend on the stickiness of the name, so the
change would be compatible. In some cases, the change would be an
improvement. Even in the worst case where someone depends on stickiness,
it's extremely straightforward to write the couple of lines of code to
produce an application based on MAKE-SYMBOL that is at least as flexible
as GENSYM, and often moreso.
Cost of Non-Adoption:
Good programmers would avoid using the argument to GENSYM (or using
GENSYM altogether) in many situations where they ought not have to.
Benefits:
Gensyms which appear to convey information through their name would not
accidentally pop out and cause confusion in places where they oughtn't.
Aesthetics:
Unnecessary global state changes are hard to reason about. This would
be a small simplification.
Discussion:
Pitman claims to have written a non-sticky GENSYM function for nearly
every one of the dozen or so large systems that he's written or worked
on in the last decade in order to get around the stated problem.
Others have suggested similar experience.
Pitman supports the proposal.
----- End Forwarded Messages -----
∂14-Mar-89 1730 CL-Compiler-mailer issue COMPILED-FUNCTION-REQUIREMENTS, version 4
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89 17:29:45 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 557112; 14 Mar 89 20:27:21 EST
Date: Tue, 14 Mar 89 20:27 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131544.AA02070@defun.utah.edu>
Message-ID: <19890315012722.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
I much prefer the option FLUSH, which was in version 2 but has been
removed. That option was to remove the COMPILED-FUNCTION type.
This type has no portable meaning and never should have existed.
I have no objection to the proposed specification of what the COMPILE
and COMPILE-FILE functions do, but it should be decoupled from the
COMPILED-FUNCTION type and discussed under the rubric of those two
functions. The parts about COMPILER-LET and EVAL-WHEN can probably be
removed (assuming the COMPILER-LET-CONFUSION proposal that eliminates
the possibility of COMPILER-LET binding any variables at run time
passes, and the EVAL-WHEN-NON-TOP-LEVEL proposal passes) since they are
redundant; there is never any interpeter/compiler difference for
COMPILER-LET or EVAL-WHEN any more.
∂14-Mar-89 1731 X3J13-mailer Issue: COERCE-INCOMPLETE (Version 3)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Mar 89 17:31:00 PST
Received: from Semillon.ms by ArpaGateway.ms ; 14 MAR 89 14:29:58 PST
Date: 14 Mar 89 14:24 PST
From: masinter.pa@Xerox.COM
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: X3J13@sail.stanford.edu
reply-to: cl-cleanup@sail.stanford.edu
line-fold: no
Message-ID: <890314-142958-1976@Xerox>
There are a couple of "additional comments" on the proposal
at the end.
!
Issue: COERCE-INCOMPLETE
Reference: COERCE (p50)
Category: ADDITION/CHANGE
Edit history: Version 1 of COERCE-INCOMPLETE, 26-Feb-88 by M. Ida
Version 1 of COERCE-FROM-TYPE, 20-Jun-88 by Pitman
Version 2 of COERCE-INCOMPLETE, 21-Nov-88 by Pitman
(consolidate previous two proposals)
Version 3 of COERCE-INCOMPLETE, 07-Mar-89 by Pitman
(eliminate unpopular proposal, two new options)
Problem Description:
COERCE is difficult to extend because ambiguities arise about the
source type of the coercion.
For example, if the symbol STRING were permitted as a second argument
to coerce, as in (COERCE NIL 'STRING), there would be two posssible
return values: "" or "NIL". The choice would be arbitrary and would
have to be specified by the documentation. No matter which was chosen,
it would probably turn out to be a problem for some applications at
some times.
Another example is (COERCE (CHAR-CODE #\A) 'STRING). This might
return the same as (FORMAT NIL "~D" (CHAR-CODE #\A)) -- "65" in
most ASCII-based implementations -- or it might return "A". Again,
the choice would be arbitrary.
There is clear desire on the part of the user community to lift some of
the existing restrictions on arguments to COERCE, but because of legitimate
concerns about ambiguities, the Common Lisp designers have thus far
refused to do so.
Unfortunately, the failure of COERCE to handle these cases means it is
very difficult to learn to use COERCE. And the fact that COERCE is not
easily learned contributes to difficulty in learning Common Lisp because
instead of a single coercion operator with general purpose semantics, a
number of very special purpose coercion operators must be learned instead.
Some middle ground needs to be found, which neither compromises the
clear semantics and portable nature of COERCE nor complicates COERCE
in a way that makes it unlearnable.
Also, some people have expressed a desire for COERCE to be more
`symmetric.' Usually they seem to mean that they want it to be the case
that if (COERCE x y) works, then (COERCE (COERCE x y) (TYPE-OF x))
should also work. Although this is not an essential desire, it would
certainly be nice to achieve.
Proposal (COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION):
Define COERCE to accept the following equivalences:
1. (COERCE x 'STRING) == (STRING x)
2. (COERCE x 'PATHNAME) == (PATHNAME x)
3. (COERCE x 'RATIONAL) == (RATIONAL x)
Clarify that
4. (COERCE x 'FLOAT) == (FLOAT x)
Rationale:
Many users think of STRING, for example, as ``the way to coerce
something to a string'' and are baffled why COERCE and STRING
disagree on how to do this.
Such users think that if there's a moral battle to be waged
over how to coerce an object to a STRING, the battle has already
been lost by defining the STRING function -- that whatever
decision is made for STRING must also apply to COERCE for the
sake of simplicity.
Similar arguments can be made for PATHNAME, FLOAT, and RATIONAL.
Proposal (COERCE-INCOMPLETE:DEPRECATE):
Deprecate COERCE.
Rationale:
COERCE is not functionally necessary -- no operation that it does
cannot be done in some other way. As such, it is basically just
a matter of syntactic convenience, and perhaps isn't worth having
around if it will be the subject of endless debate. Deprecating
it would allow us to declare this issue a `dead end' and focus our
attention on matters of greater substance.
Current Practice:
Presumably No one implements either of the proposals at this time,
since none are compatible with CLtL.
Cost to Implementors:
COERCE: Small to moderate.
DEPRECATE: None.
Cost to Users:
COERCE: This is an incompatible change. (COERCE 'NIL 'STRING) => ""
but (STRING NIL) => "NIL". How many applications are impacted by
this change is not clear. It would be straightforward to shadow
COERCE with an alternate definition that did the old thing in
cases where people were worried. Once such cases have been
identified, rewriting
(COERCE X 'STRING)
as
(IF X (COERCE X 'STRING) "")
will suffice in most cases.
DEPRECATE: No immediate work would be needed, although many maintained
applications would get upgraded in order to use the primitives that
are `in vogue.'
Cost of Non-Adoption:
People will continue to see and debate the issues alluded to in
the Problem Description.
Benefits:
The cost of Non-Adoption will be avoided.
Aesthetics:
COERCE: Many people will probably see the idea of making
COERCE consistent with STRING, PATHNAME, FLOAT, and
RATIONAL as a clear improvement -- possibly outweighing
the costs of both an incompatible change and a decision
to arbitrarily favor one treatment over the other.
DEPRECATE: Some may take the deprecation of COERCE as an
aesthetic improvement because it eliminates the need to
debate this issue further. Others may see the
``de-centralization'' of coercion as a step backward.
Discussion:
Pitman supports COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION.
Hopefully Moon and Masinter support it, too, since it's
basically patterned after a bunch of mail they were sending
back and forth.
A proposal to extend COERCE to permit a ``view type'' argument
was considered and rejected as too extreme to consider seriously
in the timeframe available.
Pierson suggests that COERCE ought to be a candidate for
generic function status.
Pitman thinks that making [two-argument] COERCE generic would
be a -very- bad idea but believes that his earlier proposal
involving a third `view type' argument might be able to
accomodate such extension.
!
Additional comments
I agree that this is ready to send out. The thing about
COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION that strikes fear
into my heart is that it wipes out CLtL's simple statement that
any sequence type may be converted to any other sequence type,
and starts people asking questions like does
(coerce nil '(vector character)) => "" or "NIL"?
This concern is not reflected at all in the writeup.
I agree that this is ready to send out but I'm inclined to vote
no on both proposals and keep the (unsatisfactory) status quo.
----- -----
I believe that any change to the status quo is incomplete without
providing a coercion mechanism whose "viewpoint" is that of a sequence.
That is effectively what the current COERCE is, overloaded with those
types which do not conflict with SEQUENCE.
Because of the problem of differing viewpoints, I'm inclined to think
that COERCE should be shrunk down to only being a sequence coercion
function, and all other coercions should be handled by the appropriate
functions.
----- -----
∂15-Mar-89 0520 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89 05:19:57 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAR 89 05:14:05 PST
Date: 15 Mar 89 05:13 PST
From: masinter.pa@Xerox.COM
to: X3J13@Sail.stanford.edu
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
reply-to: cl-cleanup@sail.stanford.edu
line-fold: NO
Message-ID: <890315-051405-3472@Xerox>
At the January '89 meeting, Version 4 of this issue was amended,
and then accepted.
We think there were some wording problems with the amendment,
in that it ended up not saying what we think was intended.
The amendment made some meaningful programs have undefined
behavior, and left the meaning of SIMPLE-ARRAY unclear.
After a good deal of work by the members of the cleanup committee,
we've arrived at the following version, which we would like
to submit to you for consideration as to whether it more
properly reflects the intent of the group.
!
Issue: ADJUST-ARRAY-NOT-ADJUSTABLE
References: ADJUST-ARRAY (p297), ADJUSTABLE-ARRAY-P (p293),
MAKE-ARRAY (pp286-289), simple arrays (p28, 289)
Category: CLARIFICATION
Edit history: 22-Apr-87, Version 1 by Pitman
15-Nov-88, Versions 2a,2b,2c by Pitman
02-Dec-88, Version 3 by Pitman
11-Jan-89, Version 4 by Pitman
16-Jan-89, Version 5, by Gabriel. Amended at the meeting to shorten.
23-Jan-89, Version 6, by Moon. Shorten without the bug introduced
by the amendment, add clarification of SIMPLE-ARRAY type.
15-Feb-89, Version 7, by Pitman. Minor changes per comments from
RPG and Dalton.
11-Mar-89, Version 8, by Pitman. Change category, add endorsements.
Problem Description:
The description of the :ADJUSTABLE option to MAKE-ARRAY on p288
says that ``the argument, if specified and not NIL, indicates that
it must be possible to alter the array's size dynamically after
it is created. This argument defaults to NIL.''
The description of the :ADJUSTABLE option does not say what
MAKE-ARRAY will do if the argument is unsupplied or explicitly NIL.
The description of ADJUSTABLE-ARRAY-P on p293 says that it is
true ``if the argument (which must be an array) is adjustable, and
otherwise false.'' However, the description of MAKE-ARRAY makes
it clear that this is not necessarily the same as asking if
the array was created with :ADJUSTABLE T. If ADJUSTABLE-ARRAY-P
returns NIL, you know that :ADJUSTABLE NIL was supplied (or no
:ADJUSTABLE option was supplied), but if ADJUSTABLE-ARRAY-P returns
T, then there is no information about whether :ADJUSTABLE was used.
The description of ADJUST-ARRAY on pp297-298 says that it is
``not permitted to call ADJUST-ARRAY on an array that was not
created with the :ADJUSTABLE option.'' This is inconsistent with
ADJUSTABLE-ARRAY-P.
A problem which comes up in practice is that some programmers
expect runtime error checking if they have done
(MAKE-ARRAY ... :ADJUSTABLE NIL) and they later try to adjust
the array using ADJUST-ARRAY.
The definition of the SIMPLE-ARRAY type and its subtypes needs
clarification of its relationship to adjustability.
Proposal (ADJUST-ARRAY-NOT-ADJUSTABLE:CLARIFY):
1. ADJUSTABLE-ARRAY-P is true of all arrays created with a true
:ADJUSTABLE option to MAKE-ARRAY. Whether ADJUSTABLE-ARRAY-P is
true of some other arrays is unspecified.
2. If MAKE-ARRAY is called with the :ADJUSTABLE, :FILL-POINTER,
and :DISPLACED-TO arguments each either unspecified or false, the
resulting array is a simple array. (This just repeats what CLtL
says on page 289, it's here to aid in understanding the next point.)
3. If MAKE-ARRAY is called with one or more of the :ADJUSTABLE,
:FILL-POINTER, or :DISPLACED-TO arguments true, whether the
resulting array is simple is unspecified.
4. ADJUST-ARRAY ``should signal'' an error if ADJUSTABLE-ARRAY-P
of its first argument is false. ADJUST-ARRAY must not signal an
`array not adjustable' error if ADJUSTABLE-ARRAY-P of its first
argument is true.
5. The value of ADJUSTABLE-ARRAY-P on a simple array is unspecified.
Note: ``should signal'' is taken from the new error terminology.
It means that in ``safe code'' (code compiled with highest safety)
an error must be signalled, but that in unsafe code (code not compiled
with highest safety), an error might or might not be signalled.
Clarifications and Logical Consequences:
a. Whether an array can be both simple and adjustable is unspecified.
b. There is no specified way to create an array for which ADJUSTABLE-ARRAY-P
definitely returns NIL.
c. There is no specified way to create an array that is non-simple.
d. This legitimizes ADJUSTABLE-ARRAY-P as an appropriate predicate to
determine whether ADJUST-ARRAY will reliably succeed.
e. If ADJUST-ARRAY is invoked on an array that was created without
supplying :ADJUSTABLE true, an `array not adjustable' error
``should be signalled'' unless ADJUSTABLE-ARRAY-P returns true on
that array (in which case it must not signal an `array not adjustable'
error).
Rationale:
This effectively makes the status quo explicit. This preserves the
raison d'etre of simple arrays, which is to provide a portable interface
to implementation-dependent specialized arrays that trade decreased
functionality for faster access.
Specifying the points left unspecified (requiring all simple arrays to be
non-adjustable and all adjustable arrays to be non-simple) would require
large changes to some implementations and would be of little benefit to
users, merely making one kind of nonconforming program fail in all
implementations instead of failing only in some implementations. The
argument here is not that the error checking would not be useful for
developers of portable code, but only that the cost of introducing that
error checking would be exceedingly high for some implementations.
Users need to know that certain arrays are simple, so they can put in
declarations and get higher performance, but users have no need to be
able to create arrays that are definitely non-simple (for lower
performance) or definitely non-adjustable (to cause errors).
Examples:
1. The following program is conforming. It is unspecified which branch
of the IF it follows.
(defun double (a)
(if (adjustable-array-p a)
(adjust-array a (* (length a) 2))
(let ((new (make-array (* (length a) 2))))
(replace new a :end1 (length a))
new)))
(double (make-array 30))
2. The following program is conforming. In no implementation is the
type declaration violated.
(let ((a (make-array 100)))
(declare (simple-array a))
(frob a))
Current Practice:
Probably everyone is compatible with this proposal.
Symbolics Genera makes :ADJUSTABLE NIL arrays adjustable in most cases,
and ignores adjustability in deciding whether an array is simple,
and is compatible with this proposal.
Lucid, IIM, and Symbolics Cloe make :ADJUSTABLE NIL arrays non-adjustable
in all cases, and make all arrays non-simple unless the Common Lisp
language requires them to be simple, and are compatible with this proposal.
Cost to Implementors:
It's in principle possible that some implementation would have to change,
but in practice there are no known implementations that would have to change.
Cost to Users:
None. This is a fully compatible change from the user's standpoint.
Benefits:
Users would know what to expect.
Non-Benefits:
Users who expect adjusting arrays created with :ADJUSTABLE NIL to signal
an error would not get the desired error checking.
Aesthetics:
Most people believe the status quo is unaesthetic. Having an aspect of
the language explicitly unspecified is more aesthetic than having it
implicitly unspecified on account of vague or inconsistent documentation.
Discussion:
Pitman, Moon, Gabriel, and Steele support this amended proposal.
MACSYMA ran into portability problems due to the status quo.
If the issue had been documented, that would have helped.
Encouraging implementations that are able to at least make
(MAKE-ARRAY ... :ADJUSTABLE NIL) create non-adjustable arrays
where possible would help, too.
We considered proposals to incompatibly change this primitive in a
variety of ways, but the community was very split with strong proponents
and opponents of each alternate proposal.
The overriding concern driving this proposal is that Symbolics
has asserted that most of the other really interesting proposals would
likely involve a sizable cost to implementors (and their installed bases)
to implement what were judged by some as gratuitous changes from the
status quo.
Pitman wishes some of the other proposals were economically feasible to
pursue but reluctantly agrees that maintaining (and clearly documenting)
the status quo is probably the most reasonable avenue left to us.
∂15-Mar-89 0622 X3J13-mailer BASE-CHARACTER
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89 06:22:19 PST
Received: from Semillon.ms by ArpaGateway.ms ; 15 MAR 89 06:09:24 PST
Date: 15 Mar 89 06:07 PST
From: masinter.pa@Xerox.COM
Subject: BASE-CHARACTER
To: CL-Characters@SAIL.STANFORD.EDU
cc: X3J13@SAIL.STANFORD.EDU
Message-ID: <890315-060924-3563@Xerox>
There were a couple of points that were only tersly alluded to in my note
on the character proposal.
BASE-CHARACTER
I think most of the confusions and problems with BASE-CHARACTER in the
proposal result from its definition in terms of the 'natural' encoding of
an implementation.
I think defining BASE-CHARACTER exactly as
(UPGRADED-ARRAY-ELEMENT-TYPE 'STANDARD-CHAR)
has all of the right properties. (Recall that UPGRADED-ARRAY-ELEMENT-TYPE
was added by the (passed) proposal in ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS.)
This definition is unambiguous and shows the relationship between the
string encoding and array upgrading strategies of the implementation and
the important character types. It ensures STANDARD-CHAR is a subtype of
BASE-CHARACTER.
Whether a character is "base" really only depends on the way that an
implementation represents strings, and not any other properties of the
implementation or the host operating system. Imagine two implementations on
a Unix machine, one of which encodes all strings as 16-bit characters, and
another which has two kinds of strings: 8-bit strings and 16-bit strings.
In the first implementation, the BASE-CHARACTER is CHARACTER: there's only
one kind of string. In the second implementation, the BASE-CHARACTER would
be those that could be stored in an 8-bit string, and it would be a proper
sub-type of CHARACTER.
To make this change requires leaving STANDARD-CHAR in the standard and then
merely defining BASE-CHARACTER in terms of it. Clearly BASE-STRING, if such
a name is necessary, would then just be a shorthand for (VECTOR
BASE-CHARACTER) with all the semantics implied by the array-element-type
proposals.
∂15-Mar-89 0636 X3J13-mailer Issue IN-PACKAGE-FUNCTIONALITY (Version 8)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89 06:35:51 PST
Received: from Semillon.ms by ArpaGateway.ms ; 15 MAR 89 06:27:41 PST
Date: 15 Mar 89 06:27 PST
From: masinter.pa@Xerox.COM
Subject: Issue IN-PACKAGE-FUNCTIONALITY (Version 8)
To: X3J13@sail.stanford.edu
reply-to: cl-cleanup@sail.stanford.edu
line-fold: NO
Message-ID: <890315-062741-3597@Xerox>
Version 4 of this issue (with only a version of
the SELECT-ONLY proposal) was discussed and tabled
at the last meeting.
This version includes two proposals; NEW-MACRO
(favored by many members of the cleanup committee)
and a new version of SELECT-ONLY.
!
Issue: IN-PACKAGE-FUNCTIONALITY
References: IN-PACKAGE (p182-183)
Category: CHANGE
Edit history: 07-Jul-88, Version 1 by Pitman
7-Oct-88, Version 2 by Masinter (discussion)
8-Dec-88, Version 3 by Masinter
12-Dec-88, Version 4 by Masinter
20-Jan-89, Version 5 by Loosemore
30-Jan-89, Version 6 by Loosemore
10-Mar-89, Version 7 by Loosemore
15-Mar-89, Version 8 by Masinter
(add back SELECT-ONLY)
Related-Issues: DEFPACKAGE (passed)
COMPILE-FILE-SYMBOL-HANDLING
Problem Description:
There are two typical uses for IN-PACKAGE -- to define/create a package
and to select a package. The fact that these two purposes have been
given to the same function has led to reduced error checking.
A more general problem is that the "Put In Seven Extremely Randoms"
convention described in CLtL is now recognized by many people as being
unsatisfactory for both package definition and package selection.
The DEFPACKAGE macro provides a much cleaner mechanism for package
definition, but there is still a need for a convenient way to select
a package that has well-defined compilation semantics.
Proposal (IN-PACKAGE-FUNCTIONALITY:NEW-MACRO):
Add a new macro:
SELECT-PACKAGE name [macro]
This macro causes *PACKAGE* to be set to the package named NAME,
which must be a symbol or string. An error is signalled if the
package does not already exist. Everything this macro does is also
performed at compile time if the call appears at top-level.
Remove the function IN-PACKAGE from the standard.
Remove the second paragraph of section 11.7 in CLtL. (This includes
the requirement for special compile-time treatment of the various
package functions.)
Rationale:
This could allow improved error checking and modularity, with only
minimal loss of functionality.
The rationale for proposing SELECT-PACKAGE as a replacement for
IN-PACKAGE, rather than simply changing IN-PACKAGE to have this
behavior, is that such an incompatible change would be confusing to
many people, and would make it more difficult to detect obsolete
usages. There is nothing in this proposal that would prevent
implementations from continuing to provide IN-PACKAGE as an extension.
Making SELECT-PACKAGE a macro rather than a function means that there
is no need to require COMPILE-FILE to handle it specially. Since
DEFPACKAGE is also defined to side-effect the compilation environment,
there is no need to require any of the package functions to be treated
specially by the compiler.
The language in section 11.7 of CLtL puts the burden on
implementations of ensuring that all symbols in a file which is
compiled and loaded end up in the same package that they would if the
source file were loaded interpretively. No implementation can
possibly meet this requirement because, in general, the runtime
behavior of the program cannot be predicted by the compiler.
Current Practice:
Probably no one implements this behavior exactly since it's an
incompatible change to CLtL.
Cost to Implementors:
The SELECT-PACKAGE macro can be implemented trivially by using
EVAL-WHEN in its expansion:
(defmacro select-package (name)
`(eval-when (eval compile load)
(setq *package*
(or (find-package ',name)
(error "Package ~s does not exist." ',name)))))
The changes required to COMPILE-FILE to remove the magic treatment
of the package functions are also likely to be small.
Cost to Users:
In most cases, minor syntactic changes to some files would be
necessary. Programmers that are now using the "Put In Seven
Extremely Randoms" convention will probably find it straightforward
to convert their code to do a DEFPACKAGE followed by a
SELECT-PACKAGE.
Cost of Non-Adoption:
The specification of COMPILE-FILE will be much more difficult to
understand.
The standard will require compilers to solve the halting problem.
Benefits:
Modular package declarations would be encouraged and errors due
to demand-creation of packages would be easier to detect.
The specification of COMPILE-FILE will be simplified.
There will be a clear statement of the requirements for program
conformance, as relating to usage of packages.
Aesthetics:
The fact that IN-PACKAGE is currently ambiguous about intent (whether
the package should exist already or not) is clearly not aesthetic.
Removing it can't be any worse.
The fact that the currently stated requirements for handling of
the package functions by the compiler are not implementable is
clearly not aesthetic.
!
Proposal (IN-PACKAGE-FUNCTIONALITY:SELECT-ONLY):
Eliminate the ability of IN-PACKAGE to create a package on demand.
Eliminate the :NICKNAMES and :USE arguments to IN-PACKAGE, since they
are no longer needed.
The results of calling IN-PACKAGE if the package does not already
exist are implementation dependent; implementations "should signal"
an error, or otherwise provide the user with a way to recover from
the situation.
Examples:
#1: (IN-PACKAGE 'NO-SUCH-PACKAGE) ;would signal an error
#2: (DEFPACKAGE FOO ...options...) ;defines/creates a package
(IN-PACKAGE 'FOO) ;selects an existing package
Rationale:
This could allow improved error checking and modularity, with only
minimal loss of functionality.
Current Practice:
Probably no one implements this behavior since it's in direct
contradiction of both the definitions and numerous examples in CLtL.
Cost to Implementors:
As written, no change to implementations is required, but many will
want to make IN-PACKAGE signal an error. This change would be
straightforward to implement. The cost may not be trivial in all
cases, but should not be very large.
Cost to Users:
In most cases, minor syntactic changes to some files would be
necessary.
In some cases, no changes would be necessary since files may
already be doing IN-PACKAGE in situations where the author is
hoping he's made sure the real package declaration is already
loaded.
Cost of Non-Adoption:
Reduced error checking.
Less modular code.
Benefits:
Errors due to demand-creation of a package by IN-PACKAGE without
appropriate uses of the :USE or :NICKNAMES or without appropriate
calls to EXPORT, etc. afterward would be easier to detect.
Modular package declarations would be encouraged.
Aesthetics:
The fact that IN-PACKAGE is currently ambiguous about intent (whether
the package should exist already or not) is clearly not aesthetic.
Some people feel this change would be an aesthetic improvement.
Others feel that an incompatible change to IN-PACKAGE would merely
be confusing.
!
Discussion:
The dual use of IN-PACKAGE has not been helpful and is confusing.
Some people may find proposal NEW-MACRO more palatable if it merely
deprecated IN-PACKAGE, instead of removing it entirely.
Loosemore and Moon support proposal IN-PACKAGE-FUNCTIONALITY:NEW-MACRO.
Pitman says:
I support NEW-MACRO, though would really prefer you change "remove" to
"deprecate". Making this an incompatible change is gratuitous.
∂15-Mar-89 0924 CL-Characters-mailer BASE-CHARACTER
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 15 Mar 89 09:24:27 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557489; Wed 15-Mar-89 12:22:00 EST
Date: Wed, 15 Mar 89 12:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: BASE-CHARACTER
To: CL-Characters@SAIL.STANFORD.EDU
cc: X3J13@SAIL.STANFORD.EDU
In-Reply-To: <890315-060924-3563@Xerox>
Message-ID: <19890315172201.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
After thinking it over, I agree with Larry Masinter's comments
in the referenced message and the suggestion to define BASE-CHARACTER
as (UPGRADED-ARRAY-ELEMENT-TYPE 'STANDARD-CHAR).
∂15-Mar-89 0936 CL-Cleanup-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89 09:36:35 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via INTERNET with SMTP id 124413; 15 Mar 89 12:34:29 EST
Date: Wed, 15 Mar 89 12:34 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
To: cl-cleanup@sail.stanford.edu
cc: X3J13@sail.stanford.edu
In-Reply-To: <890315-051405-3472@Xerox>
Message-ID: <19890315173420.1.BARMAR@OCCAM.THINK.COM>
Date: 15 Mar 89 05:13 PST
From: masinter.pa@xerox.com
Proposal (ADJUST-ARRAY-NOT-ADJUSTABLE:CLARIFY):
Hooray! We finally got our collective acts together on this one!
barmar
∂15-Mar-89 0948 X3J13-mailer Issue: GENSYM-NAME-STICKINESS (Version 1)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89 09:48:17 PST
Received: from fafnir.think.com by Think.COM; Wed, 15 Mar 89 12:44:45 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Wed, 15 Mar 89 12:46:05 EST
Received: by verdi.think.com; Wed, 15 Mar 89 12:42:51 EST
Date: Wed, 15 Mar 89 12:42:51 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903151742.AA02653@verdi.think.com>
To: cl-cleanup@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: masinter.pa@xerox.com's message of 14 Mar 89 14:56 PST <890314-145716-2049@Xerox>
Subject: Issue: GENSYM-NAME-STICKINESS (Version 1)
Does KMP intend that GENSYM not be sticky for an integer argument
as well? That is, there is no way to reset the counter?
--Guy
∂15-Mar-89 1016 X3J13-mailer Issue: EXTRA-RETURN-VALUES (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 15 Mar 89 10:16:01 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557537; Wed 15-Mar-89 13:12:57 EST
Date: Wed, 15 Mar 89 13:12 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTRA-RETURN-VALUES (Version 2)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242235.AA14585@decwrl.dec.com>
Message-ID: <19890315181252.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
This one took longer than the others to answer because it is
a more difficult issue.
Date: 24 Feb 89 17:35
From: chapman%aitg.DEC@decwrl.dec.com
Problem: Is it OK to return extra values from Common Lisp functions?
Proposal: EXTRA-RETURN-VALUES:NO
Unless it is explicitly allowed in the standard,
if a standard function
returns a different number of return values from the number
specified by the standard, the results are unspecified.
I see a couple of problems with this. First, it is bootless to
prohibit extra return values without also forbidding returning
fewer values than specified. For example, when SUBTYPEP returns
NIL NIL, both NILs must actually be returned, not defaulted.
Second, I don't understand how "the results are unspecified" can be
correct here. First of all, that term doesn't appear in the error
terminology, and I don't know whether you meant "the return values are
unspecified" or "the consequences are unspecified". But I don't see
how you could mean either of those, since in fact what happens when
a certain number of values is returned is fully specified by the
language, and there is neither ambiguity nor implementation freedom.
If we look at the Rationale:
The reason is that
additional arguments are visible to otherwise portable programs. "For
instance, (multiple-value-call #'cons (floor x y)) looks portable, but it
will try to pass the wrong number of arguments to CONS if FLOOR returns an
extra value."
I think what you must have actually meant to propose is: Functions
specified in the standard must return exactly the number of values
specified in the standard, no more and no fewer. You could phrase this
as a requirement on implementations or as something that a conforming
program is permitted to assume, I don't much care which.
I found 21 functions in the LISP package in Symbolics Genera 7.4 that
return multiple values. Is this the correct number? Just as it was
useful to know that there are exactly 775 symbols in the LISP package
(in CLtL Common Lisp), it would be a useful check to publish the number
of functions that are supposed to return more than one value, and also
the number that are supposed to return no values.
I found two functions that return a different number of values than
CLtL specifies. GETHASH returns a third value, the key it found,
to go with the value it found (this might not be EQL to the argument
when the test is EQUAL or EQUALP). READ-LINE returns two additional
values, the delimiter character and the input-editor argument given
to the delimiter character. The first of these is a useful feature
that Common Lisp ought to have, the second is a necessary extension
for our environment that is not obviously useful in other environments.
After making and thinking about that assessment, my feeling is that I
would vote for this proposal if it was reworded in a way that I could
understand (which might or might not be what I suggested above) and if a
few specific functions (list to be supplied later) were specified to
allow additional values. I think this list would include all of the I/O
functions and would not include any of the arithmetic functions. I
haven't yet consulted with anyone else at Symbolics on this opinion,
though.
∂15-Mar-89 1018 X3J13-mailer BASE-CHARACTER
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89 10:17:14 PST
Received: from fafnir.think.com by Think.COM; Wed, 15 Mar 89 13:13:21 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Wed, 15 Mar 89 13:14:40 EST
Received: by verdi.think.com; Wed, 15 Mar 89 13:11:29 EST
Date: Wed, 15 Mar 89 13:11:29 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903151811.AA02727@verdi.think.com>
To: CL-Characters@sail.stanford.edu
Cc: X3J13@sail.stanford.edu
Subject: BASE-CHARACTER
Larry's suggestion about defining BASE-CHARACTER to be simply
(UPGRADED-ARRAY-ELEMENT-TYPE 'STANDARD-CHAR) has a great deal
of charm, and I don't see anything wrong about it.
So I support it.
--Guy
∂15-Mar-89 1227 X3J13-mailer Re: Issue ERROR TERMINOLOGY, dpANS C
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89 12:27:28 PST
Received: from snail.Sun.COM (snail.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.0)
id AA14532; Wed, 15 Mar 89 12:27:45 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA13443; Wed, 15 Mar 89 12:23:50 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA28038; Wed, 15 Mar 89 12:27:22 PST
Date: Wed, 15 Mar 89 12:27:22 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903152027.AA28038@clam.sun.com>
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Subject: Re: Issue ERROR TERMINOLOGY, dpANS C
Cc: x3j13@sail.stanford.edu
Discussion continued on cl-editorial.
∂15-Mar-89 1446 X3J13-mailer Issue ERROR TERMINOLOGY
To: x3j13@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Is it the case that ``fatal'' is well-defined? If so, ``harmless'' is
simply something that is not fatal. According to my mathematics
education, that renders the term well-defined.
``Indeed, there is no way to invoke GC in Common Lisp and with a few
exceptions such as messages, GC must have NO side effects.''
Unsolicited messages can happen, and there is a proposal on the
cl-editorial table to render them harmless. If GC can have no side
effects, then why not state that and not wonder about unsolicited
messages? If we did that, then any Common Lisp that does print a
progress note is *out* of conformance.
Also, as I've said several times, rehashing, termination of processes,
progress messages, flushing IO buffers, closing streams, and a list of
possibly hundreds of things are side effects of GC that should be
guaranteed harmless (that is, not fatal).
``> Some things are not immediately harmful but may cause
> trouble later on.
Yes, lots of things are that way.''
The definition of fatal puts no time constraints on the fatality. Therefore,
neither does its negation.
``> By ``unpredictable but harmless'', I think we are in effect saying
> ``not completely unpredictable''. That is, we promise something but
> don't quite say what it is. For example, Lisp will presumably not
> break off and start playing chess. But maybe it's harmless to start
> playing chess.''
The beauty of a specification is knowing what not to say in order to
allow rational interpreters the freedom to interpret rationality now
and in the unpredictable future. There is considerable genius in the
fine line that Steele tread in CLtL on this. Does anyone rationally
think that a Common Lisp would be taken seriously that while GCing
broke out in a game of chess or an Irish gig? I refuse to seriously
debate with anyone who would use that as an example of something that
we must utter one word in the specification to prevent.
``As far as I can see, the only reasonable option is to specify
some range of possible consequences. The constraints, whatever
they may be, make it possible to reason about what the program
will do.''
The reason this won't easily work is that it presumes that we are able
to accurately predict future implementation techniques and even to
fully comprehend current ones. I'm sure that KMP or I could supply an
endless stream of new and bizarre cases that have to be explicitly
dealt with. (I single out KMP because he has uncanny creativity.)
But, I'll change the debate a little. I've claimed that ``harmless''
is well-defined if and only if ``fatal'' is well-defined or at least
defined well enough. So, to convince me that ``harmless'' should be
pitched, you must convince me that ``fatal'' must be pitched.
-rpg-
∂15-Mar-89 1451 CL-Compiler-mailer Issue SAFE-CODE, version 1
To: cl-compiler@SAIL.Stanford.EDU, x3j13@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
According to my understanding of the dictionary definitions,
``unsafe'' means primarily ``the opposite or reversal of `safe' '' and
secondarily ``not safe.'' This coincides with Moon's reading.
Therefore, I propose we use the term ``nonsafe'' which clearly means
``not safe.'' This, coupled with the already very explicit definition
of ``unsafe,'' which explains that unsafe code might actually be safe,
should take care of his objection.
-rpg-
∂15-Mar-89 1506 CL-Editorial-mailer Re: Issue ERROR TERMINOLOGY, dpANS C
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 15 Mar 89 15:06:13 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa11469; 15 Mar 89 19:24 GMT
Date: Wed, 15 Mar 89 19:21:20 GMT
Message-Id: <2039.8903151921@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue ERROR TERMINOLOGY, dpANS C
To: Cris Perdue <cperdue@sun.com>, chapman <@decwrl.dec.com:chapman@aitg.dec>
Cc: kempf <@sun.com:kempf@clam>, peck <@sun.com:peck@clam>,
sgadol <@sun.com:sgadol@clam>, x3j13@sail.stanford.edu,
cl-editorial@sail.stanford.edu, rpg <@sail.stanford.edu:rpg@lucid.com>
Perhaps this discussion should be in cl-editorial...
> From: Cris Perdue <cperdue@com.sun>
> The error terminology is OK, except for "consequences
> are unspecified". That concept is broken, though it
> has serious defenders. For example, Dick Gabriel says,
>
> "If we were to drop this term, then every time we are
> ``explicitly vague'' a valid possibility is that a fatal
> error can occur. How is it any better to say that what happens
> when some operation happens is ``explicitly vague''."
Perhaps the problem is that "harmless" is not very well defined.
Maybe we can convince ourselves that ``the consequences of the garbage
collector when invoked'' are harmless, but how many other examples can
we find? Some things are not immediately harmful but may cause
trouble later on. For example, are the consequences of using EQ to
compare numbers harmless? Suppose we know that a fatal error will not
immediately occur. Is that enough to make it harmless (in this case)?
[I know this is most likely to be a case where the ``return values are
unspecified'', but it was the best I could do on short notice, and we
can ask whether these consequences would be ``harmless'' even if they
wouldn't be described as such in the standard.]
By ``unpredictable but harmless'', I think we are in effect saying
``not completely unpredictable''. That is, we promise something but
don't quite say what it is. For example, Lisp will presumably not
break off and start playing chess. But maybe it's harmless to start
playing chess.
> A typical area of "explicit vagueness" is the destructive operations
> on lists. The explicit vagueness here is quite limited. For
> some operations any top level cell of certain lists may or may
> not be modified. Similar statements apply to other operations.
> The consequences are far from being unspecified but harmless.
> They are CONSTRAINED but meaningful.
This is an interesting example. First, there's the question ``the
consequences of what?'' The consequences of applying the destructive
operation? The consequences of doing anything that depends on whether
or not cells were modified? We really have to see how these phrases
are used in the actual description of a function.
Maybe what we want is this:
The result is a list with certain (specified) properties.
The side effects on cells in the argument list are unspecified.
In addition, there might be a general warning that the consequences of
depending on unspecified side effects are undefined.
In an earlier message, Cris Perdue said:
Let's pick a few actual examples where the language definition is
proposed to say "consequences are unspecified". (Go ahead, I
challenge you.) I think we will find that the description will
have to be more specific than that. It can make sense to say that
"effect X may or may not occur". It can make sense to say that
"data structure Y may be modified arbitrarily". If we can define a
set of effects that we consider harmless, and change "unpredictable
but harmless" to just "harmless", or some such, that could also
make sense, but not the current language.
I am not quite convinced by this argument. We have to be careful not
to make too much undefined. If we consider some operation, some
things may be specified, some things left open, and so on. The
description may have to be ``more specific'' in that we shouldn't
describe the whole thing as ``unspecified'' when we can instead say
something more precise; but that doesn't show that some parts of the
description cannot reasonably use ``unspecified'' or ``undefined''.
Besides, this argument applies just as well to ``undefined'' as it
does to ``unspecified'' -- there would be the same need to be more
specific. So again I suspect it is the ``harmless'' that is really at
fault.
Anyway, the draft C standard makes a somewhat different distinction
between ``unspecified'' and ``undefined''. In particular, correct
programs may have unspecified behavior; those with undefined behavior
are incorrect, or at least nonportable:
Unspecified behavior -- behavior, for a correct program construct
and correct data, for which the Standard imposes no requirements.
Undefined behavior -- behavior, upon use of a nonportable or
erroneous program construct, of erroneous data, or of
indeterminately-values objects, for which the Standard imposes no
requirements. Permissible undefined behavior ranges from ignoring
the situation completely with unpredictable results, to behaving
during translation or program execution in a documented manner
characteristic of the environment (with or without the issuance of a
diagnostic message), to terminating translation or execution (with
the issuance of a diagnostic message).
There is also a category of ``implementation-defined behavior".
An example: in a function call if the argument types or the number of
arguments are wrong [this is said more precisely in the standard]
``the behavior is undefined''. However: ``The order of evaluation of
the function designator, the arguments, and subexpressions within the
arguments is unspecified, but there is a sequence point before the
actual call."
The Rationale (a separate document) says:
The terms unspecified behavior, undefined behavior, and
implementation-defined behavior are used to categorize the result of
writing programs whose properties the Standard does not, or cannot,
completely describe. The goal of adopting this categorization is to
allow a certain variety among implementations which permits quality
of implementation to be an active force in the marketplace, as well
as to allow certain popular extensions, without removing the cachet
of conformance to the standard. An appendix to the standard, A.6,
catalogs those behaviors that fall into one of these three
categories.
Unspecified behavior gives the implementor some latitude in
translating programs. This latitude does not extend so far as
failing to translate the program.
Undefined behavior gives the implementor license not to catch
certain program errors that are difficult to diagnose. It also
identifies areas of possible conforming language extension: the
implementor may augment the language by providing a definition of
the officially undefined behavior.
From all this I conclude that we probably do need both unspecified and
undefined. However, it is unclear exactly what distinction they
should express.
[The C standard also distinguishes between strictly conforming [more or
less: portable] programs and conforming programs.]
-- Jeff
∂15-Mar-89 1553 X3J13-mailer Re: Issue: EXTRA-RETURN-VALUES
Received: from ti.com by SAIL.Stanford.EDU with TCP; 15 Mar 89 15:52:37 PST
Received: by ti.com id AA13974; Wed, 15 Mar 89 15:08:09 CST
Received: from Kelvin by tilde id AA23610; Tue, 14 Mar 89 11:36:42 CST
Message-Id: <2814888931-7906489@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Tue, 14 Mar 89 11:35:31 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: chapman%aitg.DEC@decwrl.dec.com
Cc: x3j13@sail.stanford.edu
Subject: Re: Issue: EXTRA-RETURN-VALUES
In-Reply-To: Msg of 24 Feb 89 17:35 from chapman%aitg.DEC@decwrl.dec.com
> Proposal: EXTRA-RETURN-VALUES:NO
> Unless it is explicitly allowed in the standard,
> if a standard function
> returns a different number of return values from the number
> specified by the standard, the results are unspecified.
>
>
> Rationale:
>
> The reason is that
> additional arguments are visible to otherwise portable programs. "For
> instance, (multiple-value-call #'cons (floor x y)) looks portable, but it
> will try to pass the wrong number of arguments to CONS if FLOOR returns an
> extra value."
This may be a bit of over-kill. I suggest making this restriction only
for functions which the standard specifies as returning multiple values.
For functions that the standard says return one value, there would be no
reason for a portable program to go out of its way to accept more than
one value from them, so additional values shouldn't hurt.
Also, "the results are unspecified" doesn't seem to be the right
terminology to use here since this is intended to be a restriction on
the implementation. How about:
Unless it is explicitly allowed in the standard, functions which are
specified to return other than one value may not be extended by
implementations to return more values than specified.
∂15-Mar-89 1603 X3J13-mailer Feb. 21 letter ballot
Received: from ti.com by SAIL.Stanford.EDU with TCP; 15 Mar 89 16:00:39 PST
Received: by ti.com id AA14034; Wed, 15 Mar 89 15:09:30 CST
Received: from home by tilde id AA26164; Tue, 14 Mar 89 13:07:13 CST
Received: by home id AA15845; Tue, 14 Mar 89 13:07:05 CST
Date: Tue, 14 Mar 89 13:07:05 CST
From: David Bartley <bartley@home.csc.ti.com>
Message-Id: <8903141907.AA15845@home>
To: x3j13@sail.stanford.edu
Subject: Feb. 21 letter ballot
Reply-To: Bartley@ti-csl.csc.ti.com
This is TI's vote on the Feb. 21 letter ballot:
________________________________________________________________________
Issue or section name | Version | Y | I | A |
------------------------------------------------------------------------
CUT-OFF-DATES | 4 | Y | | |
------------------------------------------------------------------------
ERROR-TERMINOLOGY | 5 | | I | |
------------------------------------------------------------------------
FONTS | 2 | Y | | |
------------------------------------------------------------------------
TOC | 1 | Y | | |
------------------------------------------------------------------------
Section 1.8 | 5.8 | | I | |
------------------------------------------------------------------------
Section 2.3 | 5.8 | | I | |
------------------------------------------------------------------------
Section 2.4 | 5.8 | Y | | |
------------------------------------------------------------------------
Section 2.5 | 5.8 | Y | | |
------------------------------------------------------------------------
Section 6.1 | 5.8 | Y | | |
------------------------------------------------------------------------
Concerning ERROR-TERMINOLOGY: We understand that this section is
undergoing a significant rewrite.
(By the way, in the definition of CONFORMING CODE, shouldn't there be
a third point saying that conforming code does not depend on the
results of any "undefined" or "unspecified" situations?)
Concerning Section 1.8: This writeup is too terse to be very meaningful
---it looks like a preliminary outline instead of a final draft.
Concerning Section 2.3: Page 2-13 of the draft concerns David Gray
because it does not include any of the classes from page 1-17 of
88-002R. Why did we go through all that hassle of redefining the
FUNCTION type if it is not going to be defined here as a class?
Shouldn't all of the classes on page 1-17 be included?
--db--
∂15-Mar-89 1722 X3J13-mailer Bartley's Comments
To: x3j13@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
David writes:
``(By the way, in the definition of CONFORMING CODE, shouldn't there be
a third point saying that conforming code does not depend on the
results of any "undefined" or "unspecified" situations?)''
The descriptions of unspecified and undefined already state exactly this.
Do you think it should be repeated in the definition of conforming code?
-rpg-
∂15-Mar-89 1756 X3J13-mailer Issue: BREAK-ON-WARNINGS-OBSOLETE (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89 17:56:25 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAR 89 17:17:14 PST
Date: 15 Mar 89 17:16 PST
From: masinter.pa@Xerox.COM
Subject: Issue: BREAK-ON-WARNINGS-OBSOLETE (Version 1)
To: x3J13@sail.stanford.edu
line-fold: NO
reply-to: CL-CLEANUP@Sail.stanford.edu
Message-ID: <890315-171714-1269@Xerox>
!
Issue: BREAK-ON-WARNINGS-OBSOLETE
Forum: Cleanup
References: *BREAK-ON-WARNINGS* (CLtL p432, CL Condition System p40)
*BREAK-ON-SIGNALS* (CL Condition System p25)
Category: CLARIFICATION/CHANGE
Edit history: 07-Mar-89, Version 1 by Pitman
Problem Description:
With the advent of *BREAK-ON-SIGNALS*, *BREAK-ON-WARNINGS* is
redundant and unnecessary.
Proposal (BREAK-ON-WARNINGS-OBSOLETE:DEPRECATE):
Deprecate *BREAK-ON-WARNINGS*.
Test Case:
N/A
Rationale:
This will lead to simplification of the description of WARN.
Not only are the two variables overkill, but they have an effect
in an identifiably but uselessly distinct place.
Current Practice:
Since deprecation is not removal, presumably everyone who conforms
is compatible.
Cost to Implementors:
Since the feature is deprecated rather than flushed: none.
Cost to Users:
Since the feature is deprecated rather than flushed: none.
Users should get used to writing (SETQ *BREAK-ON-SIGNALS* 'WARNING)
rather than (SETQ *BREAK-ON-WARNINGS* T).
Cost of Non-Adoption:
The definition of WARN will be gratuitously cluttered.
Benefits:
Cost of non-adoption is avoided.
Aesthetics:
Slight improvement.
Discussion:
Pitman thinks this is a good idea, but doesn't think a lot of time
should be wasted discussing the issue if there is strong opposition.
∂15-Mar-89 1853 X3J13-mailer Re: Issue: EXTRA-RETURN-VALUES
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 15 Mar 89 18:53:34 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA03073; Wed, 15 Mar 89 17:50:24 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA04907; Wed, 15 Mar 89 17:50:16 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903160050.AA04907@defun.utah.edu>
Date: Wed, 15 Mar 89 17:50:14 MST
Subject: Re: Issue: EXTRA-RETURN-VALUES
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: chapman%aitg.DEC@decwrl.dec.com, x3j13@sail.stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Tue, 14 Mar 89 11:35:31 CST
> Date: Tue, 14 Mar 89 11:35:31 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> This may be a bit of over-kill. I suggest making this restriction only
> for functions which the standard specifies as returning multiple values.
> For functions that the standard says return one value, there would be no
> reason for a portable program to go out of its way to accept more than
> one value from them, so additional values shouldn't hurt.
I disagree. I've been known to use an idiom like
(multiple-value-call #'foo (fn1) (fn2))
where FN1 is a standard Common Lisp function which is supposed to return
one value, and FN2 is a function that returns multiple values. If FN1
is allowed to return extra values, this won't work.
-Sandra
-------
∂15-Mar-89 1941 CL-Compiler-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
Received: from moon.src.honeywell.com (ALTURA.HONEYWELL.COM) by SAIL.Stanford.EDU with TCP; 15 Mar 89 19:40:55 PST
Return-Path: <alarson@src.honeywell.com>
Received: from pavo.SRC.Honeywell.COM by moon.src.honeywell.com (5.59/smail2.6.3/06-17-88);
Wed, 15 Mar 89 21:39:48 CST id AA08835 for cl-compiler@sail.stanford.edu
Posted-Date: Wed, 15 Mar 89 21:38:06 CST
Received: by pavo.src.honeywell.com (3.2/SMI-3.2)
id AA16529; Wed, 15 Mar 89 21:38:06 CST
Date: Wed, 15 Mar 89 21:38:06 CST
From: alarson@src.honeywell.com (Aaron Larson)
Message-Id: <8903160338.AA16529@pavo.src.honeywell.com>
To: cl-compiler@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Mon, 13 Mar 89 15:50:07 -0700 <8903132250.AA02499@defun.utah.edu>
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
If we permit the compiler to signal warnings for functions where the
compile-time environment signature is different from the function call
being compiled, why do we prohibit it for generic functions?
From COMPILE-ENVIRONMENT-CONSISTENCY:
(3) The compiler *must not* make any additional assumptions about
consistency between the compiletime and runtime environments. In
particular:
(a) The compiler may not ... It is, however,
permissible for the compiler to emit warning messages when
compiling calls to functions that are defined in the compiletime
environment, but where the wrong number or type of arguments
are supplied.
But then in CLOS-MACRO-COMPILATION:
DEFMETHOD:
* The method is not callable at compile-time. If there is a generic
function with the same name at compile-time, compiling a DEFMETHOD
will not add the method to that generic function. The compiler may
perform tests for lambda-list congruence only between the DEFGENERICs
and DEFMETHODs for a given generic function name that appear within
the file being compiled, and not against a generic function of the
same name which exists in the compile-time environment.
∂16-Mar-89 0601 X3J13-mailer Re: issue COMPILER-VERBOSITY, version 6
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 06:01:53 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 05:48:37 PST
Date: 16 Mar 89 05:47 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue COMPILER-VERBOSITY, version 6
To: cl-compiler@sail.stanford.edu
cc: x3J13@sail.stanford.edu
Message-ID: <890316-054837-3596@Xerox>
The current practice of this proposal says that one implementation has a
:VERBOSE that is used for what this proposal calls :PRINT, gives no current
examples of :VERBOSE, etc. I'm suspicious of a proposal to add something
that is significantly more complex than what any current implementation
already has.
COMPILE-FILE is significantly more part of the "environment" than LOAD is,
and I think that the less we specify its behavior, the better off we are.
While there are useful programmatic portable invocations of LOAD where
controlling the output behavior portably is important, the case for
portable control of output behavior of COMPILE-FILE is much less strong.
What about environments that support incremental compilation? Where
compilation is handled by a background process? Wouldn't this be
unnecessary junk for them to add?
If we have some doubts about whether some of these 'puppies' are really
useful, shouldn't we leave them behind? Not require them?
Larry
∂16-Mar-89 0632 X3J13-mailer Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 06:32:40 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 06:23:30 PST
Date: 16 Mar 89 06:22 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message
of Tue, 14 Mar 89 20:27 EST
To: cl-compiler@sail.stanford.edu
cc: X3J13@sail.stanford.edu
Message-ID: <890316-062330-3633@Xerox>
I think the previous sentiment was more strongly toward removing
COMPILED-FUNCTION rather than tightening its definition. However, in the
heat of the FUNCTION-TYPE discussion, this seemed to be a controversial
backward incompatibility (why not just leave it in, but leave it
unspecified?)
I've extracted some quotes about COMPILED-FUNCTION from the CL-CLEANUP
discussion on FUNCTION-TYPE. Of course, these are taken out of context...
Return-Path: <@SAIL.STANFORD.EDU:Moon@STONY-BROOK.SCRC.Symbolics.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 02 MAR 87 21:29:49 PST
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 2 Mar
87 21:27:23 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by
STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 82Date: Tue, 3
Mar 87 00:26 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Tue, 3 Mar 87 00:26 EST
It might be wise to add LEXICAL-CLOSURE and INTERPRETED-FUNCTION data
types, to go along with the COMPILED-FUNCTION type that already exists.
These three would be disjoint subtypes of FUNCTION, but not necessarily
an exhaustive partition. There might be other ways to slice the space
of types, since it's not so clear what a function not inside a closure
is good for. Alternatively we could flush COMPILED-FUNCTION and say
that the subtypes of FUNCTION are all implementation-dependent. But I
think having COMPILED-FUNCTION without the others is weird.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:FAHLMAN@C.CS.CMU.EDU>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 08 MAR 87 21:56:23 PST
Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 8 Mar 87
21:53:10 PST
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Mon 9 Mar 87 00:53:51-EST
Date: Mon, 9 Mar 87 00:53 EST
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
Probably we should explicitly name COMPILED-FUNCTION and
INTERPRETED-FUNCTION as subtypes of FUNCTION, and make TYPEP work for
them.
- - - - - - - - -
Return-Path: <RPG@SAIL.STANFORD.EDU>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 08 MAR 87 23:54:05 PST
Date: 08 Mar 87 23:51 PST
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Possibly these should not be required to be pairwise disjoint (?).
I think we shouldn't presume that all implementations implement
functions as closures. I can imagine an implementation with
COMPILED-FUNCTIONs, INTERPRETED-FUNCTIONs, COMPILED-CLOSUREs,
and INTERPRETED-CLOSUREs.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:FAHLMAN@C.CS.CMU.EDU>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 09 MAR 87 08:07:46 PST
Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 9 Mar 87
08:01:49 PST
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Mon 9 Mar 87 10:57:49-EST
Date: Mon, 9 Mar 87 10:57 EST
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
Well, these make sense only in systems that do support both compiled and
interpreted code. In compiler-only or interpreter-only systems, I guess
the best move would be to say that every function is a member of both of
these subtypes: it is both a fast function and a slow function.
Now you're the one who is letting the user see internal stuff that is
none of his concern. All of these functions are closures, in that they
no longer have any free variables waiting to be closed. In some cases,
there may have been none in the first place, and implementors may want
to use some efficient internal form in such cases, but is there any
reason the user needs to know that? A confusing concept that does him
no good (I think).
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:Moon@STONY-BROOK.SCRC.Symbolics.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 10 MAR 87 07:54:56 PST
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 10 Mar
87 07:48:09 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by
STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 89098; Tue
10-Mar-87 01:57:50 EST
Date: Tue, 10 Mar 87 01:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
... I vacillate between
saying that all of the subtypes of FUNCTION are implementation-dependent
and shouldn't be standardized (thus COMPILED-FUNCTION should be
removed), and saying that programs might want to know this information,
so all the plausible subtypes should have standard names, even if they
aren't distinct in some implementations. The only thing I feel strongly
and consistently about is that COMPILED-FUNCTION should not be the only
standardized subtype of FUNCTION; it should either acquire some siblings
or go away.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:KMP@STONY-BROOK.SCRC.Symbolics.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 13 MAY 87 00:13:57 PDT
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 May
87 00:12:36 PDT
Received: from TSUKUBA.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM
via CHAOS with CHAOS-MAIL id 138655; Wed 13-May-87 03:10:55 EDT
Date: Wed, 13 May 87 03:10 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
* It seems to me that we might as well go ahead and create types
INTERPRETED-FUNCTION and COMPILED-FUNCTION since the combination of
the FUNCTION type and the COMPILED-FUNCTION-P predicate already
implements
this distinction. Perhaps eventually COMPILED-FUNCTION-P could be
flushed.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:FAHLMAN@C.CS.CMU.EDU>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 17 MAY 87 19:32:45 PDT
Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 17 May 87
19:31:22 PDT
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Sun 17 May 87 22:30:44-EDT
Date: Sun, 17 May 87 22:30 EDT
Message-ID: <FAHLMAN.12303231779.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
One possibility is not to define any of these and to eliminate
COMPILED-FUNCTION-P. That's what I proposed in version 3. The other
possibility is to define COMPILED-FUNCTION and INTERPRETED-FUNCTION as
subtypes of FUNCTION, but then we have to spell out what happens in
implementations that have only one internal representation or that have
more than two -- raw interpreted, transformed, and fully compiled, for
example. Then there's the question of whether closures are, or can be,
a separate subtype. In some sense, all true functions are closures,
since to get one you close a lambda expression in some lexical
environment. However, we might want to reserve the word "closure" for
functions that actually capture some part of the lexical context outside
the function itself, and to create CLOSURE types based on this idea.
In my view, we are better off avoiding this whole thing and leaving it
to the individual implementations.
- - - - - - - - -
Date: 29 May 87 21:18 PDT
Subject: Issue: FUNCTION-TYPE (version 4)
From: Masinter.pa
Proposal FUNCTION-TYPE:REDEFINE
...
No sub-types of FUNCTION are defined in Common Lisp, but implementations
are free to define subtypes of FUNCTION. Examples might be
COMPILED-FUNCTION, INTERPRETED-FUNCTION, and so on. Note that this
is a change from the current Common Lisp definition which explicitly
defines a COMPILED-FUNCTION type. This proposal removes the predicate
COMPILED-FUNCTION-P from the standard language.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:Moon@STONY-BROOK.SCRC.Symbolics.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 01 JUN 87 21:23:10 PDT
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 1 Jun
87 21:21:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 161267; Tue
2-Jun-87 00:11:30 EDT
Date: Tue, 2 Jun 87 00:11 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
This proposal removes the predicate
COMPILED-FUNCTION-P from the standard language.
If it also removes the COMPILED-FUNCTION type-specifier, say so here.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:Masinter.pa@Xerox.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 13 JUL 87 12:58:35 PDT
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Jul 87 12:54:07
PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 JUL 87 12:54:07 PDT
Date: 13 Jul 87 12:53 PDT
From: Masinter.pa
... My notes [from X3J13 meeting] include ... that we be more consistent
about justifying removing COMPILED-FUNCTION-P (i.e., why bother?) ...
- - - - - - - - -
Date: 23 Oct 87 11:51 PDT
From: Masinter.pa
Subject: Issue: FUNCTION-TYPE (Version 6)
here is a revised version... I left COMPILED-FUNCTION and
COMPILED-FUNCTION-P as subtypes of FUNCTION.
...
Proposal FUNCTION-TYPE:STRICT-REDEFINITION
...
The COMPILED-FUNCTION subtype of FUNCTION is defined; implementations are
free to define other subtypes of FUNCTION, e.g., INTERPRETED-FUNCTION.
- - - - - - - - -
(wording preserved through several iterations)
- - - - - - - - -
Return-Path: <CL-Cleanup-mailer@SAIL.Stanford.EDU>
Redistributed: xerox-cl-cleanup↑.pa
Received: from SAIL.Stanford.EDU by Xerox.COM ; 16 FEB 88 09:41:39 PST
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Feb 88
09:39:23 PST
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA23751; Tue, 16 Feb 88 10:39:08 MST
Received: by orion.utah.edu (5.54/utah-1.0-slave)
id AA25191; Tue, 16 Feb 88 10:39:04 MST
From: sandra%orion@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8802161739.AA25191@orion.utah.edu>
Date: Tue, 16 Feb 88 10:39:02 MST
Also, I have a question about 1b, where it states that COMPILED-FUNCTION
is a subtype of FUNCTION. Does this imply that it must be a *proper*
subtype? For example, in the Lisp I've been working on sporadically for
my Atari, the interpreted version of (FUNCTION (LAMBDA ...)) returns a
compiled function object (it's a closure which will apply the lambda
expression to the function arguments). Likewise I can conceive of
implementations which compile everything and don't have an "interpreter"
at all. I think this needs to be clarified.
- - - - - - - - -
Return-Path: <CL-Cleanup-mailer@SAIL.Stanford.EDU>
Redistributed: xerox-cl-cleanup↑.pa
Received: from SAIL.Stanford.EDU by Xerox.COM ; 19 FEB 88 14:37:22 PST
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 19 Feb 88 14:34:11
PST
Received: from Cabernet.ms by ArpaGateway.ms ; 19 FEB 88 14:17:33 PST
Date: 19 Feb 88 14:17 PST
From: Masinter.pa
I intended not to require that it not be a "proper" subtype in the sense
that
there may be no data items that are FUNCTIONP but not COMPILED-FUNCTIONP.
This can be clarified.
- - - - - - - - -
Return-Path: <edsel!jonl@labrea.Stanford.EDU>
Received: from labrea.Stanford.EDU by Xerox.COM ; 24 FEB 88 10:14:38 PST
Received: by labrea.Stanford.EDU; Wed, 24 Feb 88 09:35:20 PST
Received: from bhopal.lucid.com by edsel id AA21578g; Wed, 24 Feb 88
10:03:43 PST
Received: by bhopal id AA26979g; Wed, 24 Feb 88 10:09:26 PST
Date: Wed, 24 Feb 88 10:09:26 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Lucid Common Lisp distinguishes "compiled" closures which exist for the
purpose of supporting entry into the interpreter from functions which are
truly compiled. It only takes a bit in a header word. If an
implementation
really doesn't support an interpreter, then having every function be
COMPILED-FUNCTIONP doesn't sound like much of a loss.
But most implementations in fact do support an interpreter -- which
typically runs code at anywhere from 30 to 600 times slower than when
compiled. Thus it seems reasonable to require COMPILED-FUNCTIONP in
those implementations to be false on, say,
(eval '#'(lambda (x) (list x)))
no matter what underlying technique is used to support interpreter
closures.
- - - - - - - - -
Date: 4 Sep 88 13:39 PDT
From: Masinter.pa
Subject: Issue: FUNCTION-TYPE (version 12)
line-fold: NO
This is the final version of the FUNCTION-TYPE issue, as passed at the June
88 X3J13 meeting; that is, it incorporates the amendments that were adopted
before the issue was adopted.
...
1b. Define that the type COMPILED-FUNCTION is a subtype of FUNCTION.
Implementations are free to define other subtypes of FUNCTION.
∂16-Mar-89 0713 X3J13-mailer Issue: TIME-ZONE-NON-INTEGER, v.1
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 07:13:51 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 07:07:49 PST
Date: 16 Mar 89 07:07 PST
From: masinter.pa@Xerox.COM
To: x3J13@sail.stanford.edu
Subject: Issue: TIME-ZONE-NON-INTEGER, v.1
line-fold: NO
Message-ID: <890316-070749-3717@Xerox>
!
Issue: TIME-ZONE-NON-INTEGER
References: Section 25.4.1 (Time Functions) (p. 443-444)
Category: CLARIFICATION
Edit history: 1-MAR-89, Version 1 by Chapman
Problem Description:
CLtL states that the time zone part of Decoded Time is an integer. However,
it is possible to have a non-integer time-zone.
Proposal (TIME-ZONE-NON-INTEGER:ALLOW)
Specify that the time zone part of Decoded Time is a rational number
(either an integer or a ratio).
Rationale:
For CL to accommodate all possible time designations, it is necessary
to allow time zone to be non-integer.
Some places in the world are on half-hour or quarter-hour times.
Current Practice:
VAX LISP allows time zone to be non-integer.
Adoption Cost:
Shouldn't be too big a change.
Benefits:
See Rationale.
Conversion Cost:
See Adoption Cost.
Aesthetics:
None.
Discussion:
∂16-Mar-89 0720 X3J13-mailer Issue: LOAD-TRUENAME (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 07:20:34 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 07:13:53 PST
Date: 16 Mar 89 07:13 PST
From: masinter.pa@Xerox.COM
Subject: Issue: LOAD-TRUENAME (Version 1)
To: x3J13@SAIL.Stanford.EDU
Message-ID: <890316-071353-3747@Xerox>
!
Issue: LOAD-TRUENAME
Forum: Cleanup
References: LOAD (p426), PROVIDE (p188), REQUIRE (p188),
Issue REQUIRE-PATHNAME-DEFAULTS
Category: ADDITION
Edit history: 13-Mar-89, Version 1 by Pitman
Problem Description:
It is difficult to construct sets of software modules which work
together as a unit and which port between different implementations.
REQUIRE and PROVIDE were intended to provide this level of support
but have `failed' to be portable in practice.
Typical user configurations involve a `system definition' file which
loads the modules of a `system' (collection of software modules).
Among the specific problems which arise are:
- File system types may vary. Different file syntax must be used for
each site.
- Even with the same Lisp implementation and host file system type,
the directory in which a software system resides may differ from
delivery site to delivery site.
- Multiple `copies' of the same system may reside in different
directories on the same machine.
Proposal (LOAD-TRUENAME:NEW-PATHNAME-VARIABLES):
Introduce new variables:
*LOAD-TRUENAME* [Variable]
This special variable is initially NIL, but is bound by LOAD to
hold the truename of the pathname of the file being loaded.
*COMPILE-FILE-TRUENAME* [Variable]
This special variable is initially NIL, but is bound by
COMPILE-FILE to hold the truename of the pathname of the file
being compiled.
Example:
------ File SETUP ------
(IN-PACKAGE 'MY-STUFF)
(DEFMACRO COMPILE-TRUENAME () `',*COMPILE-FILE-TRUENAME*)
(DEFVAR *SOURCE-FILE* (COMPILE-TRUENAME) "Just for debugging.")
(DEFVAR *LOADED-FILE* *LOAD-TRUENAME*)
(DEFUN LOAD-MY-SYSTEM ()
(DOLIST (MODULE-NAME '("FOO" "BAR" "BAZ"))
(LOAD (MERGE-PATHNAMES MODULE-NAME *LOAD-TRUENAME*))))
------------------------
(LOAD "SETUP")
(LOAD-MY-SYSTEM)
Rationale:
This satisfies the most common instances of the frequently reported
problem in the Problem Description.
Current Practice:
Wide variation.
In some implementations, calling LOAD binds or sets
*DEFAULT-PATHNAME-DEFAULTS* so that pathnames named in a file being
LOADed will default to being `nearby.'
Some implementations provide special variables that are similar or
identical to one or both of those proposed.
Some implementations have a way to represent the pathname for the
current working directory, and make the default pathname default
to that, so that loading without specifying a default again tends to
get `nearby' files.
None of these techniques is portable, unfortunately, because there
is no agreement.
Cost to Implementors:
Very small.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Continued difficulty for anyone trying to put a system of modules
in a form where they can be conveniently delivered using portable code.
Benefits:
The cost of non-adoption is avoided.
Aesthetics:
Negligible.
Discussion:
Touretzky raised the issue most recently on Common-Lisp. A number
of people immediately jumped on the bandwagon, indicating it was
important to them, too.
Pitman made three suggestions in response, of which the above is
the first. The others included:
2. Variables *LOAD-TRUENAMES* and *COMPILE-FILE-TRUENAMES* which hold
lists of the truenames of all files being loaded or compiled,
respectively, during the dynamic invocation of LOAD and COMPILE-FILE.
3. Variable *LOAD-OR-COMPILE-FILE-TRUENAMES* which holds a list like
((LOAD truename) (COMPILE-FILE truename) ...)
during the dynamic invocation of LOAD and COMPILE-FILE.
Touretzky responded:
``I like KMP's proposals. I like the second one best: have separate
variables for files being loaded and files being compiled, and use
them to maintain a stack so we can see the nesting of loads within
files.''
Pitman ultimately chose to present the first rather than the second
because it seemed simpler, easier to explain, and more likely to
pass at this late date.
!
Additional Comments:
"I favor LOAD-TRUENAME:NEW-PATHNAME-VARIABLES. I think this
proposal would be greatly improved by adding two more variables,
*LOAD-PATHNAME* and *COMPILE-FILE-PATHNAME*, whose values are
the pathname opened by LOAD or COMPILE-FILE, rather than the
truename. The need for these is more obvious if you think
about systems where the pathname cannot be easily reconstructed
from the truename. This includes file systems with symbolic
links and some pathname systems with logical pathnames."
"I favor this. I would even favor either of the other two ideas even at
this `late date'. The behavior of each of the proposals is simple, its
easy to see what it will and won't do, and it satisfies a real demand.
I should note that I have never wanted the incremented functionally
offered by the `stack' proposals, but I could still vote for them."
∂16-Mar-89 0708 CL-Compiler-mailer Re: Issue SAFE-CODE, version 1
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 07:08:22 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 07:03:17 PST
Date: 16 Mar 89 07:02 PST
From: masinter.pa@Xerox.COM
Subject: Re: Issue SAFE-CODE, version 1
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 15 Mar 89
14:51 PST
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: cl-compiler@SAIL.Stanford.EDU, x3j13@SAIL.Stanford.EDU
Message-ID: <890316-070317-3708@Xerox>
I'm guessing that Moon's objections are more serious than yours.
Frankly, as long as we're playing definitions, I think the problem lies
with
"Define that, formally, the term ``safe code'' is code refers to any
code in which the OPTIMIZE quality for SAFETY has a value of 3."
I don't think this is a good definition. It is probably good to define that
"any code in which the OPTIMIZE quality for SAFETY has a value 3" is "safe
code", but there is other code that is "safe" too.
It seems pretty awkward to say that:
(locally (declare (optimize (safety 0))) (list 1 2 3))
is "unsafe" or "nonsafe" or "potentially non-safe". We could use the words
that way, but it is pretty confusing.
Counter-proposal: say "declared safe" or "not declared safe", since the
issue is not the (English) safety of the code but the declarations in
effect?
∂16-Mar-89 0719 X3J13-mailer Re: issue LOAD-TIME-EVAL, version 11
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Mar 89 07:19:03 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA21484; Thu, 16 Mar 89 08:16:34 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05509; Thu, 16 Mar 89 08:16:32 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903161516.AA05509@defun.utah.edu>
Date: Thu, 16 Mar 89 08:16:30 MST
Subject: Re: issue LOAD-TIME-EVAL, version 11
To: masinter.pa@Xerox.COM
Cc: x3j13@sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM, 16 Mar 89 06:45 PST
> Date: 16 Mar 89 06:45 PST
> From: masinter.pa@Xerox.COM
>
> Um, I looked for and didn't find a justification for why what was passed at
> the last meeting was inadequate. I'm puzzled as to why there are now two
> proposals when there was one before, what the differences are between them,
> etc.
What happened is that we got some e-mail on this issue after the
meeting, describing in more detail some objections to the wording of
the proposal that had been discussed very briefly at the meeting.
This person thought that the original wording was too vague and that
we would have trouble being more explicit about the semantics it was
intended to specify, and suggested some new wording for slightly
different semantics. I think it is the consensus of the compiler
committee that the new language is an improvement.
The changed section of the proposal is clearly marked in the writeup
that was distributed. It has to do with under what circumstances it
is permissible to cache LOAD-TIME-VALUE expressions.
-Sandra
-------
∂16-Mar-89 0831 X3J13-mailer Issue DESCRIBE-UNDERSPECIFIED, v.1
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 08:31:39 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 08:20:29 PST
Date: 16 Mar 89 08:19 PST
From: masinter.pa@Xerox.COM
Subject: Issue DESCRIBE-UNDERSPECIFIED, v.1
To: x3j13@SAIL.STANFORD.EDU
line-fold: NO
Message-ID: <890316-082029-3881@Xerox>
!
Forum: Cleanup
Issue: DESCRIBE-UNDERSPECIFIED
References: CLtL p441-2
88-002R, DESCRIBE function
Category: CHANGE, ADDITION
Edit history: Version 1, 10-Mar-89, Kim A. Barrett
Problem description:
The CLOS Specification (X3J13 Document 88-002R) changes the definition of the
function DESCRIBE, making it a generic function. However, it does not specify
any of the protocol needed to make user-defined methods interact properly to
produce some of the effects mentioned in CLtL. For example, CLtL says that
sometimes the method for describing an object will involve describing
something that it finds inside the object, and that such recursive
descriptions are indented appropriately. How do user-written methods achieve
this indentation? Must they arrange for the indentation explicitly, or is
there some automatic mechanism that handles it?
The new specification does not easily lend itself to certain kinds of features
which some implementations have included in their versions of DESCRIBE, such
as analogues to the printer's depth limits (*PRINT-DEPTH*) and circular
structure detection during recursion (*PRINT-CIRCLE*).
In addition, DESCRIBE does not take a stream argument, instead always doing
output to *STANDARD-OUTPUT*. This means that a program which wants to use
DESCRIBE to output some information to a particular stream must rebind
*STANDARD-OUTPUT* around the call to DESCRIBE. This is a nuisance, and is
also potentially a bad idea in implementations which have interrupts and such.
Proposal DESCRIBE-UNDERSPECIFIED:DESCRIBE-OBJECT:
Remove the section of 88-002R which specifies that DESCRIBE is a generic
function. Modify DESCRIBE to accept an optional second stream argument, which
defaults to *STANDARD-OUTPUT*. The value of this argument is the stream which
output will be directed to. Specify that DESCRIBE is implemented in terms of
the generic function DESCRIBE-OBJECT, described below.
DESCRIBE-OBJECT object stream [Generic Function]
The generic function DESCRIBE-OBJECT writes a description of an object to a
stream. The function DESCRIBE-OBJECT is called by the DESCRIBE function; it
should not be called by the user.
Each implementation is required to provide a method on the class
STANDARD-OBJECT and methods on enough other classes so as to ensure that
there is always an applicable method. Implementations are free to add
methods for other classes. Users can write methods for DESCRIBE-OBJECT for
their own classes if they do not wish to inherit an implementation-supplied
method.
ARGUMENTS:
The first argument is any Lisp object. The second argument is a stream; it
cannot be T or NIL.
VALUES:
The values returned by DESCRIBE-OBJECT are unspecified.
REMARKS:
Methods on DESCRIBE-OBJECT may recursively call DESCRIBE. Indentation,
depth limits, and circularity detection are all taken care of automatically,
provided that each method handles exactly one level of structure and calls
DESCRIBE recursively argument if there are more structural levels.
If this rule is not obeyed, the results are undefined.
In some implementations the stream argument passed to a DESCRIBE-OBJECT
method is not the original stream, but is an intermediate stream that
implements parts of DESCRIBE. Methods should therefore not depend on the
identity of this stream.
Rationale:
This proposal was closely modeled on the CLOS description of PRINT-OBJECT,
which was well thought out and provides a great deal of functionality and
implementation freedom. The same implementation techniques applicable to
PRINT-OBJECT will be applicable to DESCRIBE-OBJECT.
The reason for making the return values for DESCRIBE-OBJECT unspecified is to
avoid forcing users to include explicit (VALUES) in all their methods.
DESCRIBE will take care of that.
Current practice:
Probably nobody does precisely what this proposal suggests.
Cost to Implementors:
A fair amount of work may be required, since every method/subfunction of
DESCRIBE in an implementation may need at least some fixing to be in line with
this proposal. On the other hand, that work may already be needed in order to
conform to 88-002R, and this proposal may make the conversion easier by
simplifying the translation of an existing implementation of DESCRIBE.
Cost to Users:
Any users who are using an implementation which supports the current CLOS
specification of DESCRIBE and have defined their own methods will have to
change them. CLOS is sufficiently recent that this probably isn't a big
problem.
Those users who have made use of implementation-specific hooks into DESCRIBE
to define their own methods will likely have to change, but that was already
the case.
Users who are currently binding *STANDARD-OUTPUT* around calls to DESCRIBE may
wish to change their code.
Cost of non-adoption:
Portable DESCRIBE methods may be difficult to write because the protocol they
must follow is insufficiently specified.
Benefits:
The constraints on DESCRIBE methods are better specified, making it easier to
write such methods properly.
Aesthetics:
Minimal.
Discussion:
An additional change which is not included in the present proposal would be to
make the syntax of DESCRIBE and DESCRIBE-OBJECT be
DESCRIBE object &optional stream &key
DESCRIBE-OBJECT object stream &key
allowing implementation-specific extensions to the arguments. A possible
standard keyword argument is :VERBOSE, which might be used to specify how much
output to produce.
It might be desirable to define some new describe control variables analogous
to the printer control variables, ie. *DESCRIBE-LEVEL* and *DESCRIBE-CIRCLE*,
and possibly *DESCRIBE-LENGTH*.
-------
----- End Forwarded Messages -----
∂16-Mar-89 0854 X3J13-mailer Issue: CLOS-CONDITIONS (Version 4)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 08:54:08 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 08:44:08 PST
Date: 16 Mar 89 08:43 PST
From: masinter.pa@Xerox.COM
Subject: Issue: CLOS-CONDITIONS (Version 4)
To: X3J13@SAIL.Stanford.EDU
line-fold: NO
Message-ID: <890316-084408-3922@Xerox>
There've been various comments on this version; most of the
relevant discussion centers on whether the metaclass of
condition classes should be specified. Exerpts from
the mail appear at the end.
!
Status: DRAFT
Issue: CLOS-CONDITIONS
References: Condition System (Revision 18)
Category: ADDITION
Edit history: 26-Sep-88, Version 1 by Pitman
06-Oct-88, Version 2 by Pitman
09-Oct-88, Version 3 by Pitman
10-Mar-89, Version 4 by Pitman (remove unsupported options)
Problem Description:
The description of the Common Lisp condition system presupposes
only DEFSTRUCT and not DEFCLASS because it was written when
CLOS had not been adopted. It is stylistically out of step with
CLOS in a few places and places some restrictions which are not
necessary if CLOS can be presupposed.
Proposal (CLOS-CONDITIONS:INTEGRATE):
1. Define that condition types are CLOS classes.
2. Define that condition objects are CLOS instances.
3. Functions such as SIGNAL, which take arguments of class names, are
permitted to take class objects. Such class objects must still be
subclasses of CONDITION.
4. Define that slots in condition objects are normal CLOS slots. Note
that WITH-SLOTS can be used to provide more convenient access to the
slots where slot accessors are undesirable.
5. Incompatibly change the syntax of a slot in DEFINE-CONDITION
to be compatible with a DEFCLASS slot specification.
An implication of this change is that forms like
(DEFINE-CONDITION FOO (BAR) ((A 1) (B 2)))
would have to be written
(DEFINE-CONDITION FOO (BAR)
((A :INITARG :A :READER FOO-A :INITFORM 1)
(B :INITARG :B :READER FOO-B :INITFORM 2)))
6. Permit multiple parent-types to be named in the list of parent types.
Define that these parent types are treated the same as the superior
class list in a CLOS DEFCLASS expression.
7. Eliminate the :CONC-NAME option to DEFINE-CONDITION.
8. Define that condition reporting is mediated through the PRINT-OBJECT
method for the condition type (class) in question, with *PRINT-ESCAPE*
always being NIL. Specifying (:REPORT fn) in the definition of a
condition type C is equivalent to doing
(DEFMETHOD PRINT-OBJECT ((X c) STREAM)
(IF *PRINT-ESCAPE* (CALL-NEXT-METHOD) (fn X STREAM)))
Rationale:
These changes are consistent with the intent of the X3J13 endorsement
of CLOS and the Common Lisp Condition System.
Although items 5 and 7 are incompatible with the interim condition
handling which we've been working with, the overall proposal significantly
improves compatibility with CLOS.
This compatibility will make the language seem less fragmented, and
probably more learnable because there will be fewer paradigms to learn.
Also, items 5 and 7 in particular are an improvement for reasons
unrelated to CLOS if only because they get rid of the need for symbol
concatenation, a process which has been seen to cause problems because
of the transient nature of the binding of *PACKAGE*.
Examples:
Slot specifiers...
A slot specifier of X is still valid but is incompatibly
changed to mean what CLOS has it mean; no :INITARG or
:READER would be supplied.
A slot specifier of (X) is still valid but is incompatibly
changed to mean what CLOS has it mean; no :INITARG or
:READER would be supplied.
A slot specifier of (X V) would no longer be valid.
In addition, other slot specifiers such as
(X :INITARG :EX :TYPE FIXNUM)
are permitted as in DEFCLASS.
Conc names ...
(DEFINE-CONDITION FOOBAR (FOO BAR) (X Y) (:CONC-NAME FUBAR))
would be rewritten
(DEFINE-CONDITION FOOBAR (FOO BAR)
((X :INITARG :X :READER FUBAR-X)
(Y :INITARG :Y :READER FUBAR-Y)))
Report methods ...
(DEFINE-CONDITION OOPS (ERROR) ())
(DEFMETHOD PRINT-OBJECT ((X OOPS) STREAM)
(IF *PRINT-ESCAPE*
(CALL-NEXT-METHOD)
(FORMAT STREAM "Oops! Something went wrong.")))
(ERROR 'OOPS)
>>Error: Oops! Something went wrong.
Current Practice:
Some implementations supporting CLOS probably already do this,
or something very similar.
Cost to Implementors:
If you really have CLOS, this is very straightforward.
Cost to Users:
Small, but tractable.
The main potential problems are:
- :CONC-NAME. There is nothing that keeps an implementation from
continuing to support :CONC-NAME for a short while until old code
has been upgraded.
- The incompatible change to slot syntax. Again, it is possible to
unambiguously recognize a 2-list as old-style syntax and an
implementation can provide interim compatibility support during
a transition period.
Even if implementations did not provide the recommended compatibility
support, users could trivially shadow DEFINE-CONDITION and provide the
support themselves, expanding into the native DEFINE-CONDITION in the
proper syntax.
In any case, the total number of uses of DEFINE-CONDITION at this
point is probably quite small. Searching for them and repairing
each by hand is probably not an expensive operation.
Cost of Non-Adoption:
Conditions will seem harder to manipulate than other user-defined types.
People will wonder if CLOS is really something we're committed to.
Benefits:
A more regular, more learnable language.
Aesthetics:
Improved.
Discussion:
Gregor, Pierson, Moon, and Pitman support this proposal.
People seem to disagree about the status that CLOS might occupy
in the upcoming standard. In spite of a vote of support, they seem
to think it might be optional in some way. Passing this proposal
establishes a clear precedent for the full integration of CLOS into
the emerging language.
The sense of the cleanup committee was that it was acceptable for
a vendor to identify a CLOS-free subset of Common Lisp, but that since
the position of X3J13 seems to be that no resources should be devoted
to work on subsets, it was inappropriate for us to work out the details
of that subset ourselves. Since nothing about this proposal would
impede such a subset, we took that to be adequate basis for presenting
this single proposal.
Moon thinks we might want to add condition types for the errors
CLOS might signal. Richard Mlynarik thinks we should add a generic
function, REPORT-CONDITION, which is used for reporting conditions.
Both of these issues should probably be pursued under separate cover.
!
"One comment is that you should explicitly mention bootstrapping
concerns under cost to implementors. If you just leave it out,
someone may think it is a difficult problem. "
"This isn't any sort of clarification. The actual clarification required
-- which has been requested several times, and not just by myself -- is
what the *METACLASS* of condition types is.
Condition types may be "CLOS classes" without being STANDARD-CLASSes
Condition objects may be "CLOS instances" without being STANDARD-OBJECTs.
Just what are "normal CLOS slots"? As I see it, the "normalcy" or
otherwise of slots is determined by the metaclass.
My opinion for some time has been that condition types should not be
STANDARD-CLASSes but instead something like READ-ONLY-CLASS.
Conceptually, It Is An Error to modify the slots of condition objects,
which are supposed to be immutable descriptions of part of the state of
a computation. Implementationally,
(setf (slot-value <condition-object> <slot-name>) <new-value>) should
signal an error.
(I also think that conditions in particular have a strong need for
something like :REQUIRED-INIT-KEYWORDS, but that's another story.)
Even if you decide to make condition classes' metaclass STANDARD-CLASS,
the point is that you need to state this, so that users may define
condition classes and mixins using DEFCLASS."
"I do not agree that it is a -necessary- thing to specify the Meta-Class
of conditions because all intended uses of conditions can be done
without this information.
I agree that it is a -possibly useful- thing to do, but there is a down
side to it -- it would unnecessarily tie the hands of people who want
implementation flexibility for one reason or another."
"... If we don't specify the metaclass, then users
won't know what other classes they can mix in when defining condition
classes. It may seem weird, but I can imagine someone wanting to mix
in an arbitrary class into a condition class.
I think we should just say that the class CONDITION is an instance of
STANDARD-CLASS, and that by default DEFINE-CONDITION defines standard
classes. Sure it might be nice to do the read only class thing but I
don't think this is a good time to design a special purpose metaclass
for this. "
∂16-Mar-89 0928 CL-Compiler-mailer Issue SAFE-CODE, version 1
To: cl-compiler@SAIL.Stanford.EDU
CC: x3j13@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The point of these definitions is to lay out terminology that
enables programmers to know with certainty on what ground they stand
with respect to the specification. ``Safe code'' is a technical term
that means that the code was ``processed'' under this declaration.
This means intuitively that it is as safe (English word) as it can get.
But it also means that it is ``safe code'' in the CL jargon, and eveything
we say about safe code there is also true of it.
The meaning of safe code (English phrase), as in ``as safe as it can
get,'' is spelled out in the specification as the sequence of statements
we make about the attributes of safe code. It might be that some or all of
those attributes apply to code processed under lower safety optimization
levels, but the programmer can be sure only when the highest safety level
is used.
I think Moon's problem is that the usual practice is to borrow English
words for these technical terms, and that works fine until the
negation of the term is needed. We want some word to mean ``not `safe' ''.
``Unsafe'' is an available English word that does not mean the
complement of ``safe'', it means the reverse of safe. Thus, the parallel
senses of the technical pair ``safe/unsafe'' are not the same as the
vernacular pair safe/unsafe.
Also, the definitions of the terms point out that what is defined as
``unsafe code'' might actually be exactly as safe (English) as ``safe code.''
-rpg-
∂16-Mar-89 0958 X3J13-mailer Re: Issue: EXTRA-RETURN-VALUES
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 09:57:58 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via CHAOS with CHAOS-MAIL id 124433; Wed 15-Mar-89 19:37:26 EST
Date: Wed, 15 Mar 89 19:37 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Re: Issue: EXTRA-RETURN-VALUES
To: David N Gray <Gray@dsg.csc.ti.com>
cc: chapman%aitg.DEC@decwrl.dec.com, x3j13@sail.stanford.edu
In-Reply-To: <2814888931-7906489@Kelvin>
Message-ID: <19890316003719.1.BARMAR@OCCAM.THINK.COM>
Date: Tue, 14 Mar 89 11:35:31 CST
From: David N Gray <Gray@dsg.csc.ti.com>
> Proposal: EXTRA-RETURN-VALUES:NO
> Unless it is explicitly allowed in the standard,
> if a standard function
> returns a different number of return values from the number
> specified by the standard, the results are unspecified.
>
>
> Rationale:
>
> The reason is that
> additional arguments are visible to otherwise portable programs. "For
> instance, (multiple-value-call #'cons (floor x y)) looks portable, but it
> will try to pass the wrong number of arguments to CONS if FLOOR returns an
> extra value."
This may be a bit of over-kill. I suggest making this restriction only
for functions which the standard specifies as returning multiple values.
For functions that the standard says return one value, there would be no
reason for a portable program to go out of its way to accept more than
one value from them, so additional values shouldn't hurt.
But MULTIPLE-VALUE-CALL permits multiple arguments, some of which might
be calls to functions documented as returning only one valid, e.g.
(multiple-value-call #'three-arg-function (cons x y) (floor x y))
MV-CALL is being used to get the multiple values of FLOOR passed as the
second and third argument to THREE-ARG-FUNCTION, but this will fail if
CONS returns the wrong number of values.
barmar
∂16-Mar-89 0958 X3J13-mailer Issue: TIME-ZONE-NON-INTEGER, v.1
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 09:58:20 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via INTERNET with SMTP id 124441; 16 Mar 89 12:16:49 EST
Date: Thu, 16 Mar 89 12:16 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Issue: TIME-ZONE-NON-INTEGER, v.1
To: masinter.pa@xerox.com
cc: x3J13@sail.stanford.edu
In-Reply-To: <890316-070749-3717@Xerox>
Message-ID: <19890316171639.5.BARMAR@OCCAM.THINK.COM>
Date: 16 Mar 89 07:07 PST
From: masinter.pa@xerox.com
Proposal (TIME-ZONE-NON-INTEGER:ALLOW)
Specify that the time zone part of Decoded Time is a rational number
(either an integer or a ratio).
Just to show you, when I become a billionaire I'll form my own country
and give it an irrational time zone (e in the winter, sqrt(2) in the
summer).
Seriously, is there any particular reason not to allow any non-complex
number as a time zone?
barmar
∂16-Mar-89 0957 X3J13-mailer Re: Issue ERROR TERMINOLOGY, dpANS C
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 09:57:06 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via CHAOS with CHAOS-MAIL id 124431; Wed 15-Mar-89 19:28:46 EST
Date: Wed, 15 Mar 89 19:28 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Re: Issue ERROR TERMINOLOGY, dpANS C
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
cc: Cris Perdue <cperdue@sun.com>, chapman <@decwrl.dec.com:chapman@aitg.dec>,
kempf <@sun.com:kempf@clam>, peck <@sun.com:peck@clam>, sgadol <@sun.com:sgadol@clam>,
x3j13@sail.stanford.edu, cl-editorial@sail.stanford.edu, rpg <@sail.stanford.edu:rpg@lucid.com>
In-Reply-To: <2039.8903151921@subnode.aiai.ed.ac.uk>
Message-ID: <19890316002837.0.BARMAR@OCCAM.THINK.COM>
A while back I proposed (to the Editorial committee) a definition of
"harmless" that I still like: Equivalent to an arbitrary conforming
program. The point of this definition is to say that the consequences
of the situation are undefined, but it can't do anything that a valid
program can't do (if we had a denotational semantics, or a virtual
machine specification as I believe the C standard does, we could
probably use that to specify this). For instance, it won't result in
pointers to unallocated data being stored in the application's data, or
changing components of function objects. Undefined consequences would
allow such things, and they can result in secondary effects such as
crashing the system or the process dumping core. Note that my
definition includes signaling an error among the harmless consequences.
Yes, this definition allows such situations to result in playing chess,
and if the computer is controlling a bomb silo it could also result in
starting World War III. I don't think a general definition of
"unspecified" can possibly disallow these things. We might want to
rethink the applicability of the word "harmless" in this case. I think
market forces are adequate to guarantee that the actual results in any
particular implementation will be reasonable, and we won't have
computers all over the country playing chess when you ask them to CONS.
By the way, I've decided that the "consequences of the garbage collector
are unspecified" example is totally bogus. The garbage collector is
completely transparent to a Common Lisp program. The usual
counterargument (which I used to give) is that GC usually changes the
output of the ROOM function, but so can CONS, MAKE-ARRAY, etc.; the
language doesn't even guarantee that (PROGN (ROOM) (ROOM)) will print
the same output twice (it probably won't if ROOM conses). It can also
be argued that GC can be detected by noticing how long operations take,
but on time-sharing systems there are other reasons why an operation may
take a long time. GC may reorder the elements in a hash table, but we
never guarantee that MAPHASH of a hash table will consistently process
the elements in the same order, and SETF of GETHASH may also rehash the
table. I challenge someone to write a conforming Common Lisp program
GC-P that takes as an argument a function, applies the function, and
returns a boolean result indicating whether a GC occurred during the
function execution.
If we can't come up with another example of an unspecified situation,
perhaps we should just throw out the term and stop fighting about it.
barmar
∂16-Mar-89 0958 CL-Compiler-mailer Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 09:58:47 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via INTERNET with SMTP id 124445; 16 Mar 89 12:31:52 EST
Date: Thu, 16 Mar 89 12:31 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
To: masinter.pa@xerox.com
cc: cl-compiler@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: <890316-062330-3633@Xerox>
Message-ID: <19890316173142.7.BARMAR@OCCAM.THINK.COM>
I'll just reiterate something I said at one of the meetings. One
portable use I can think of for the COMPILED-FUNCTION type is as a
declaration to allow compiler optimization. If a function knows (or
requires) that a parameter is a compiled function it can declare that
and the implementation may be able to optimize the FUNCALL better.
Another thing I just thought of is something like:
(when (typep f '(and function (not compiled-function)))
(setq f (compile nil f)))
This doesn't actually work because COMPILE isn't required to accept
lexical closures (well, at least it doesn't accept them in Genera 7.2),
but they satisfy the type specifier, but it would be nice if there were
a standard set of primitives that would allow one to write something
that does what the above tries to do.
barmar
∂16-Mar-89 1040 X3J13-mailer Re: Issue ERROR TERMINOLOGY
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 16 Mar 89 10:40:10 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08149; 16 Mar 89 18:31 GMT
Date: Thu, 16 Mar 89 18:29:06 GMT
Message-Id: <2499.8903161829@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue ERROR TERMINOLOGY
To: Dick Gabriel <RPG@sail.stanford.edu>, x3j13@sail.stanford.edu
In-Reply-To: Dick Gabriel's message of 15 Mar 89 1446 PST
> Is it the case that ``fatal'' is well-defined? If so, ``harmless'' is
> simply something that is not fatal. According to my mathematics
> education, that renders the term well-defined.
"Harmless" does not mean "not fatal".
"Undefined" means the standard imposes no constraints (and irrational
implementors can do whatever they want and still have a conforming
implementation). But "unspecified" imposes some constraints. I
didn't find "harmless" a sufficiently enlightening description of
these constraints. If no one feels inclined to suggest something
better now, I am happy to wait and see how "unspecified" gets used in
the standard before deciding whether or not "harmless" works.
∂16-Mar-89 1044 X3J13-mailer Issue: CLOSED-STREAM-OPERATION (Version 7)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 10:44:15 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 09:51:25 PST
Date: 16 Mar 89 09:43 PST
From: masinter.pa@Xerox.COM
Subject: Issue: CLOSED-STREAM-OPERATION (Version 7)
To: x3j13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-095125-4330@Xerox>
Version 5 of issue CLOSED-STREAM-OPERATION was brought up at
the January 1989 meeting.
The proposal CLOSED-STREAM-FUNCTIONS:ALLOW-INQUIRY was amended at
that meeting; the amended version passed.
Version 5 said
"If CLOSE is called on a stream which is open, it will return T.
However, if CLOSE is called on a stream which is closed, it
will succeed without error but the return value is not specified."
The amendment was to change the wording so that CLOSE would
return NIL if given a closed stream, viz:
" If CLOSE is called on a stream which is open, it will return T.
However, if CLOSE is called on a stream which is closed, it
will succeed with out error but the return value will be NIL."
Kent Pitman has made an argument that the amendment
was ill-considered.
I find his argument convincing.
I think procedurally we can vote to reconsider &
revoke the amendment, i.e., revert to Version 5.
Excerpts from the discussion:
Return-Path: <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 06 FEB 89 10:12:19 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 534168; Mon 6-Feb-89 13:11:33 EST
Date: Mon, 6 Feb 89 13:11 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
...
I think one ought not be able to depend
on the result in this case [of CLOSE of a closed stream]
because implementations might reasonably differ
about whether the first CLOSE really closed the stream. As such,
(LIST (CLOSE *TERMINAL-IO*) (CLOSE *TERMINAL-IO*))
might reasonably return (T T) or (T NIL), for example, depending on whether
the implementation represents the concept of `open-ness' for all streams.
The same is true for string streams.
The issue is even weirder for composite (eg, broadcast) streams where some
streams are initially open and others are not, since I think we have no
clear theory of whether such a stream is opened or closed.
...
Return-Path: <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 15 FEB 89 07:04:19 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 539477; Wed 15-Feb-89 10:03:58 EST
Date: Wed, 15 Feb 89 10:03 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
What's weird about this whole thing is that CLOSE-CONSTRUCTED-STREAM
talks about the effect of most operations being `unspecified' after
CLOSE.
Unless you intend it to be an implication of CLOSE-CONSTRUCTED-STREAM
that you actually carry a CLOSED-P bit around in every stream so you
can tell if the stream is open or not and return the right value from
CLOSE, then it's a bad idea to legislate that CLOSE returns a certain
value, because you can't really guarantee that value.
If you do intend me to carry around a CLOSED-P bit, why bother to
claim that the effect of I/O to the stream after it's closed is
`unspecified.' My assumption before was that it was unspecified in
case I want to define it, but suddenly it sounds like I'm not really
allowed to extend it -- I'm just permitted to optimize out the error
checks for the sake of efficiency. If this is so, why not just put it
in the domain of `should signal' so that at least the users could get
some mileage out of it because my implementation pretty much has its
hands tied at this point.
We get calls all the time from users who claim we're in violation of
things that really CLtL leaves vague. This will be such a thing given
the way it's all worded.
Here I am implementing CLOSE. I -really- want to implement it correctly.
I am willing to do anything necessary to make it return the right value
as long as what I do is something that is backed up in writing.
Here you are designing CL -- creating the writing that will back me up.
If you cannot show me how to write CLOSE in a way so that I can simply
point to a sentence in the manual that explains off my behavior whenever
anyone complains so I can get them off the phone and get back to work,
then you owe me a sentence in the manual that says that I'm entitled to
do whatever I feel like and the user cannot depend on it.
False security is worse than no security at all.
∪End of message∪
∂16-Mar-89 1051 X3J13-mailer Re: Issue ERROR TERMINOLOGY, dpANS C
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 16 Mar 89 10:51:31 PST
Received: from mist.encore.COM by multimax.encore.com with SMTP (5.61/25-eef)
id AA06620; Thu, 16 Mar 89 13:49:18 -0500
Received: from localhost by mist. (4.0/SMI-4.0)
id AA07280; Thu, 16 Mar 89 13:47:38 EST
Message-Id: <8903161847.AA07280@mist.>
To: Barry Margolin <barmar@FAFNIR.THINK.COM>
Cc: x3j13@sail.stanford.edu, cl-editorial@sail.stanford.edu
Subject: Re: Issue ERROR TERMINOLOGY, dpANS C
In-Reply-To: Your message of Wed, 15 Mar 89 19:28:00 -0500.
<19890316002837.0.BARMAR@OCCAM.THINK.COM>
Date: Thu, 16 Mar 89 13:47:36 EST
From: Dan L. Pierson <pierson@mist.encore.com>
Date: Wed, 15 Mar 89 19:28 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
A while back I proposed (to the Editorial committee) a definition of
"harmless" that I still like: Equivalent to an arbitrary conforming
program. The point of this definition is to say that the consequences
of the situation are undefined, but it can't do anything that a valid
program can't do (if we had a denotational semantics, or a virtual
machine specification as I believe the C standard does, we could
probably use that to specify this). For instance, it won't result in
pointers to unallocated data being stored in the application's data, or
changing components of function objects. Undefined consequences would
allow such things, and they can result in secondary effects such as
crashing the system or the process dumping core. Note that my
definition includes signaling an error among the harmless consequences.
I like this idea.
∂16-Mar-89 1044 X3J13-mailer Issue: COERCE-INCOMPLETE (Version 3)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 10:44:26 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 09:59:01 PST
Date: 16 Mar 89 09:57 PST
From: masinter.pa@Xerox.COM
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: x3j13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-095901-4371@Xerox>
There are some additional comments at the end.
!
Issue: COERCE-INCOMPLETE
Reference: COERCE (p50)
Category: ADDITION/CHANGE
Edit history: Version 1 of COERCE-INCOMPLETE, 26-Feb-88 by M. Ida
Version 1 of COERCE-FROM-TYPE, 20-Jun-88 by Pitman
Version 2 of COERCE-INCOMPLETE, 21-Nov-88 by Pitman
(consolidate previous two proposals)
Version 3 of COERCE-INCOMPLETE, 07-Mar-89 by Pitman
(eliminate unpopular proposal, two new options)
Problem Description:
COERCE is difficult to extend because ambiguities arise about the
source type of the coercion.
For example, if the symbol STRING were permitted as a second argument
to coerce, as in (COERCE NIL 'STRING), there would be two posssible
return values: "" or "NIL". The choice would be arbitrary and would
have to be specified by the documentation. No matter which was chosen,
it would probably turn out to be a problem for some applications at
some times.
Another example is (COERCE (CHAR-CODE #\A) 'STRING). This might
return the same as (FORMAT NIL "~D" (CHAR-CODE #\A)) -- "65" in
most ASCII-based implementations -- or it might return "A". Again,
the choice would be arbitrary.
There is clear desire on the part of the user community to lift some of
the existing restrictions on arguments to COERCE, but because of legitimate
concerns about ambiguities, the Common Lisp designers have thus far
refused to do so.
Unfortunately, the failure of COERCE to handle these cases means it is
very difficult to learn to use COERCE. And the fact that COERCE is not
easily learned contributes to difficulty in learning Common Lisp because
instead of a single coercion operator with general purpose semantics, a
number of very special purpose coercion operators must be learned instead.
Some middle ground needs to be found, which neither compromises the
clear semantics and portable nature of COERCE nor complicates COERCE
in a way that makes it unlearnable.
Also, some people have expressed a desire for COERCE to be more
`symmetric.' Usually they seem to mean that they want it to be the case
that if (COERCE x y) works, then (COERCE (COERCE x y) (TYPE-OF x))
should also work. Although this is not an essential desire, it would
certainly be nice to achieve.
Proposal (COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION):
Define COERCE to accept the following equivalences:
1. (COERCE x 'STRING) == (STRING x)
2. (COERCE x 'PATHNAME) == (PATHNAME x)
3. (COERCE x 'RATIONAL) == (RATIONAL x)
Clarify that
4. (COERCE x 'FLOAT) == (FLOAT x)
Rationale:
Many users think of STRING, for example, as ``the way to coerce
something to a string'' and are baffled why COERCE and STRING
disagree on how to do this.
Such users think that if there's a moral battle to be waged
over how to coerce an object to a STRING, the battle has already
been lost by defining the STRING function -- that whatever
decision is made for STRING must also apply to COERCE for the
sake of simplicity.
Similar arguments can be made for PATHNAME, FLOAT, and RATIONAL.
Proposal (COERCE-INCOMPLETE:DEPRECATE):
Deprecate COERCE.
Rationale:
COERCE is not functionally necessary -- no operation that it does
cannot be done in some other way. As such, it is basically just
a matter of syntactic convenience, and perhaps isn't worth having
around if it will be the subject of endless debate. Deprecating
it would allow us to declare this issue a `dead end' and focus our
attention on matters of greater substance.
Current Practice:
Presumably No one implements either of the proposals at this time,
since none are compatible with CLtL.
Cost to Implementors:
COERCE: Small to moderate.
DEPRECATE: None.
Cost to Users:
COERCE: This is an incompatible change. (COERCE 'NIL 'STRING) => ""
but (STRING NIL) => "NIL". How many applications are impacted by
this change is not clear. It would be straightforward to shadow
COERCE with an alternate definition that did the old thing in
cases where people were worried. Once such cases have been
identified, rewriting
(COERCE X 'STRING)
as
(IF X (COERCE X 'STRING) "")
will suffice in most cases.
DEPRECATE: No immediate work would be needed, although many maintained
applications would get upgraded in order to use the primitives that
are `in vogue.'
Cost of Non-Adoption:
People will continue to see and debate the issues alluded to in
the Problem Description.
Benefits:
The cost of Non-Adoption will be avoided.
Aesthetics:
COERCE: Many people will probably see the idea of making
COERCE consistent with STRING, PATHNAME, FLOAT, and
RATIONAL as a clear improvement -- possibly outweighing
the costs of both an incompatible change and a decision
to arbitrarily favor one treatment over the other.
DEPRECATE: Some may take the deprecation of COERCE as an
aesthetic improvement because it eliminates the need to
debate this issue further. Others may see the
``de-centralization'' of coercion as a step backward.
Discussion:
Pitman supports COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION.
Hopefully Moon and Masinter support it, too, since it's
basically patterned after a bunch of mail they were sending
back and forth.
A proposal to extend COERCE to permit a ``view type'' argument
was considered and rejected as too extreme to consider seriously
in the timeframe available.
Pierson suggests that COERCE ought to be a candidate for
generic function status.
Pitman thinks that making [two-argument] COERCE generic would
be a -very- bad idea but believes that his earlier proposal
involving a third `view type' argument might be able to
accomodate such extension.
!
Additional comments:
"... The thing about
COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION that strikes fear
into my heart is that it wipes out CLtL's simple statement that
any sequence type may be converted to any other sequence type,
and starts people asking questions like does
(coerce nil '(vector character)) => "" or "NIL"?
... I'm inclined to vote
no on both proposals and keep the (unsatisfactory) status quo."
"I believe that any change to the status quo is incomplete without
providing a coercion mechanism whose "viewpoint" is that of a sequence.
That is effectively what the current COERCE is, overloaded with those
types which do not conflict with SEQUENCE.
Because of the problem of differing viewpoints, I'm inclined to think
that COERCE should be shrunk down to only being a sequence coercion
function, and all other coercions should be handled by the appropriate
functions."
∂16-Mar-89 1045 X3J13-mailer DRAFT Issue: CONDITION-RESTARTS (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 10:44:53 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 10:30:53 PST
Date: 16 Mar 89 10:24 PST
From: masinter.pa@Xerox.COM
Subject: DRAFT Issue: CONDITION-RESTARTS (Version 1)
To: x3j13@SAIL.Stanford.EDU
line-fold: NO
Message-ID: <890316-103053-4587@Xerox>
There will possibly be a new version of this issue available
at the meeting. Additional comments excerpted at the end...
!
Issue: CONDITION-RESTARTS
Forum: Cleanup
References: Common Lisp Condition System
Category: CHANGE
Edit history: 18-Jan-89, Version 1 by Pitman
Problem Description:
It was noted in the condition system document itself, and many people have
complained privately, that a major weakness of the condition system is the
inability to know whether a particular restart is associated with a
particular signalling action.
The problem being addressed shows itself in situations involving recursive
errors. The programmer wants to make sure that a restart obtained from
FIND-RESTART or COMPUTE-RESTARTS is in fact present for the purpose of
handling some particular error that he is actively focussed on, and not
for some other (outer) error which he was not actively trying to handle.
Proposal (CONDITION-RESTARTS:PERMIT-ASSOCIATION):
1. Define that it is an error for SIGNAL to be called on a condition
more than once.
2. Introduce a function COPY-CONDITION:
COPY-CONDITION condition [Function]
Returns a copy of the given condition.
3. Introduce a macro WITH-CONDITION-RESTARTS which can be used to
dynamically bind the association between a condition and a set
of restarts.
WITH-CONDITION-RESTARTS (condition-form restarts-form) &BODY forms
[Macro]
Evaluates CONDITION-FORM and RESTARTS-FORM, the results of which
should be a condition and a list of restarts, respectively. Then
evaluates the body of forms in implicit-progn style, returning the
last form. While in the dynamic context of the body, the function
COMPUTE-RESTARTS will, when given an argument that was the result
of evaluating the CONDITION-FORM, return the list of restarts that
was the result of evaluating the RESTARTS-FORM.
Only the innermost call to WITH-CONDITION-RESTARTS with a given
condition is relevant. In this way, the set of restarts associated
with a given condition can be dynamically extended or restricted.
Usually this macro is not used explicitly in code, since
SIGNAL-WITH-RESTARTS and ERROR-WITH-RESTARTS handle most of the
common cases in a way that is syntactically more concise.
4. Extend COMPUTE-RESTARTS, FIND-RESTART, ABORT, CONTINUE, USE-VALUE,
and STORE-VALUE to permit an optional condition object as an argument.
When the extra argument is not supplied, these functions behave
exactly as defined before. (Restarts are considered without
prejudice to whether they have been associated with conditions.)
When this argument is supplied, only restarts with the associated
with the given condition are considered. In all other respects, the
behavior is the same.
Passing a condition argument of NIL is treated the same as passing
no condition argument.
5. Add two new macros SIGNAL-WITH-RESTARTS and ERROR-WITH-RESTARTS:
SIGNAL-WITH-RESTARTS condition &rest restart-clauses [Macro]
This does several things:
1. It enters a context in which the indicated RESTART-CLAUSES
are available. They have the same form as the clauses in
a RESTART-CASE.
2. It evaluates CONDITION expression. [This is done after the
restarts are instantiated because the restarts are probably
still useful in the debugger if an error occurs during the
evaluation of the condition.] The result of the evaluation
must be a condition object.
3. It associates the condition which resulted from the evaluation
with the restarts established in step 1, using the equivalent
of WITH-CONDITION-RESTARTS.
4. It calls SIGNAL on the same condition.
ERROR-WITH-RESTARTS condition &rest restart-clauses [Macro]
Like SIGNAL-WITH-RESTARTS but uses ERROR rather than SIGNAL
in step 4.
6. Define that Common Lisp macros such as CHECK-TYPE, which are defined
to signal and to make restarts available, use the equivalent of
WITH-CONDITION-RESTARTS to associate the conditions they signal with
the defined restarts, so that users can make reliable tests not only
for the restarts being available, but also for them being available
for the right reasons.
Rationale:
1. The ability to recycle a condition object (including the ability to
resignal a condition) means that the same condition object might be
simultaneously active for two different purposes. In such a case,
no test (not even EQ) would suffice to determine whether a particular
restart belonged with a particular signalling action, since the
condition could not uniquely identify the signalling action. By saying
that a given condition may only be signalled once, we guarantee that
the condition can serve as a unique identifier for a signalling action.
2. Since there may now be some code which has begun to rely on the ability
to re-signal a condition, COPY-CONDITION will help to make this
transition easier. Instead of
(SIGNAL already-signalled-condition)
one can write:
(SIGNAL (COPY-CONDITION already-signalled-condition))
3. This is is the minimal level of support needed to set up an
association between restarts and conditions.
4. This provides a natural interface for retrieving and using the
information about the associations between conditions and restarts.
5. This provides a natural interface for the most common case of
wanting to signal a restart with some associated conditions.
Test Case:
(HANDLER-BIND ((ERROR #'(LAMBDA (C) (SIGNAL C)))) (SIGNAL "Test"))
was permissible, but this proposal makes it an error.
(DEFUN TEST-CONDITION-STUFF (OFFER-EXTRA-RESTART
USE-CONDITION-ARGUMENT
USE-FOUND-RESTART)
(HANDLER-BIND ((CONDITION
#'(LAMBDA (C)
(LET ((R0 (FIND-RESTART 'USE-VALUE))
(R1 (IF USE-CONDITION-ARGUMENT
(FIND-RESTART 'USE-VALUE C)
(FIND-RESTART 'USE-VALUE))))
(IF (AND R1 USE-FOUND-RESTART)
(INVOKE-RESTART R1 (EQ R0 R1))
(USE-VALUE (EQ R0 R1)))))))
(HANDLER-BIND ((CONDITION
#'(LAMBDA (C)
(USE-VALUE
(IF OFFER-EXTRA-RESTART
(WITH-RESTARTS
(SIGNAL (COPY-CONDITION C))
(USE-VALUE (X) (LIST 'EXTRA X)))
(SIGNAL (COPY-CONDITION C)))))))
(SIGNAL-WITH-RESTARTS (MAKE-CONDITION 'SIMPLE-CONDITION
:FORMAT-STRING "Test")
(USE-VALUE (X) X)))))
Previously, this was an error because it uses non-existent primitives, but
if you assume that
- COPY-CONDITION is implemented in the `obvious' way
- SIGNAL-WITH-RESTARTS just uses WITH-RESTARTS and SIGNAL
- FIND-RESTART ignores its last argument
in the obvious naive ways, it is possible to compare the old and new behavior:
Current Proposed
(TEST-CONDITION-STUFF NIL NIL NIL) => T T
(TEST-CONDITION-STUFF NIL NIL T) => T T
(TEST-CONDITION-STUFF NIL T NIL) => T T
(TEST-CONDITION-STUFF NIL T T) => T T
(TEST-CONDITION-STUFF T NIL NIL) => T (EXTRA T)
(TEST-CONDITION-STUFF T NIL T) => T (EXTRA T)
(TEST-CONDITION-STUFF T T NIL) => T (EXTRA NIL)
(TEST-CONDITION-STUFF T T T) => T NIL
Current Practice:
Presumably no implementation does this yet.
Cost to Implementors:
Several small, relatively modular changes.
Cost to Users:
Except for the change to the recyclability of restarts, this change is
upward compatible.
Probably very few if any users currently take advantage of recycling
restarts, so the cost to users of this change is very slight.
Even in the case where recycling is used, a straightforward rewrite in
terms of COPY-CONDITION is probably feasible.
Cost of Non-Adoption:
Use of restarts would not be nearly as reliable.
Benefits:
It would be possible to write code which was considerably more robust.
Aesthetics:
Some people might consider this proposal to make things slightly better
because it avoids some ambiguities. Others might consider it to make
things slightly worse because it adds additional complexity.
Discussion:
Pitman thinks a change of this sort is important.
!
"CONDITION-RESTARTS:PERMIT-ASSOCIATION looks fine to me.
It would certainly clean things up in some code I'm working on.."
"I strongly favor this proposal; it removes the major objection that I
had to the CL condition system as it developed.
However, I don't favor the COPY-CONDITION function. I don't think it's
necessary. More importantly, you have not proposed any concrete specification
of what it does, and unless someone does, it cannot be included in the
language. Fortunately, I think we can just drop it, as I doubt that any
portable program would use it in any significant way that could not just
as well be done with a tiny amount of code using other existing primitives.
[generally agreed]
" .. how (should) the condition/restart association
might be implemented -- is some kind of alist structure held by a
special variable what was intended, or ought the condition have a
restarts slot? ... it's pretty obvious that the relation should be externally
represented. It's important that the association not be done by a slot
in the condition because if you carry around the condition object after
you're done signalling, you don't want it to contain useless and/or
misleading information about restarts that no longer exist."
"... syntax to SIGNAL-WITH-RESTARTS and
ERROR-WITH-RESTARTS should be:
SIGNAL-WITH-RESTARTS signal-argument-list &rest restart-clauses
ERROR-WITH-RESTARTS signal-argument-list &rest restart-clauses
so that you would write
(SIGNAL-WITH-RESTARTS ('FOOD-COLOR-ERROR :FOOD 'LETTUCE :COLOR 'PINK)
...restart clauses...)
rather than
(SIGNAL-WITH-RESTARTS (MAKE-CONDITION 'FOOD-COLOR-ERROR
:FOOD 'LETTUCE :COLOR 'PINK)
...restart clauses...)
If you wanted to use MAKE-CONDITION, you would then write:
(SIGNAL-WITH-RESTARTS ((MAKE-CONDITION 'FOOD-COLOR-ERROR
:FOOD 'LETTUCE :COLOR 'PINK))
...restart clauses...)
The advantage of what he proposes is that you could write
(SIGNAL-WITH-RESTARTS ("Bad ~S color" 'FOOD)
...restart clauses...)
and a condition object would be created implicitly as with SIGNAL. A
possible disadvantage is that
(SIGNAL-WITH-RESTARTS (FOO BAR BAZ)
...restart clauses...)
might look to someone like the FOO in (FOO BAR BAZ) named a function
rather than a variable. "
"... even better would be
(WITH-CONDITION-RESTARTS signal-form &rest restart-clauses)
where signal-form must be an invocation of SIGNAL, ERROR, WARN, or
perhaps a few others, or a macro that expands into such an invocation.
WITH-CONDITION-RESTARTS must signal an error at all levels of safety if
it does not recognize the signal-form. This is "weird" because it uses
a form for something other than evaluation (but not unprecedented; this
is exactly what SETF does). The advantage is that it just nests with an
existing syntax instead of inventing a new, awkward syntax.
Note that I stole the "good name" WITH-CONDITION-RESTARTS for this
commonly used syntax. The less commonly used primitive that just sets
up the restarts without signalling doesn't need as good a name."
"... the syntax for WITH-CONDITION-RESTARTS should be
WITH-CONDITION-RESTARTS condition-form restarts-form &BODY forms
rather than
WITH-CONDITION-RESTARTS (condition-form restarts-form) &BODY forms
which it is now. Does anyone else have an opinion?
This is probably a good idea. I'd probably name this one
WITH-CONDITION-RESTARTS-INTERNAL. But are we sure that this operation
needs to be named in the standard
"
∂16-Mar-89 1117 CL-Compiler-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89 11:16:55 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558656; Thu 16-Mar-89 14:13:55 EST
Date: Thu, 16 Mar 89 14:13 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
To: Aaron Larson <alarson@src.honeywell.com>
cc: cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
In-Reply-To: <8903160338.AA16529@pavo.src.honeywell.com>
Message-ID: <19890316191343.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 15 Mar 89 21:38:06 CST
From: alarson@src.honeywell.com (Aaron Larson)
If we permit the compiler to signal warnings for functions where the
compile-time environment signature is different from the function call
being compiled, why do we prohibit it for generic functions?
I would say that what CLOS-MACRO-COMPILATION (which I have not reviewed yet)
is clearly incorrect. Perhaps CLOS-MACRO-COMPILATION was trying only to rule
out signalling an error for a lack of lambda-list congruency between
compile-time and run-time, but went overboard and ruled out warnings
as well. I think warnings in this circumstance can be desirable, but
errors are certainly wrong.
∂16-Mar-89 1146 X3J13-mailer Issue ERROR TERMINOLOGY, dpANS C
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 11:44:03 PST
Received: from fafnir.think.com by Think.COM; Thu, 16 Mar 89 14:40:15 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Thu, 16 Mar 89 14:41:04 EST
Received: by verdi.think.com; Thu, 16 Mar 89 14:37:31 EST
Date: Thu, 16 Mar 89 14:37:31 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903161937.AA05048@verdi.think.com>
To: barmar@Think.COM
Cc: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK, cperdue@sun.com,
@decwrl.dec.com:chapman@aitg.dec, @sun.com:kempf@clam,
@sun.com:peck@clam, @sun.com:sgadol@clam, x3j13@sail.stanford.edu,
cl-editorial@sail.stanford.edu, @sail.stanford.edu:rpg@lucid.com
In-Reply-To: Barry Margolin's message of Wed, 15 Mar 89 19:28 EST <19890316002837.0.BARMAR@OCCAM.THINK.COM>
Subject: Issue ERROR TERMINOLOGY, dpANS C
Date: Wed, 15 Mar 89 19:28 EST
From: Barry Margolin <barmar@Think.COM>
A while back I proposed (to the Editorial committee) a definition of
"harmless" that I still like: Equivalent to an arbitrary conforming
program ...
Yes, this definition allows such situations to result in playing chess,
and if the computer is controlling a bomb silo it could also result in
starting World War III. I don't think a general definition of
"unspecified" can possibly disallow these things. We might want to
rethink the applicability of the word "harmless" in this case....
How about renaming "harmless" to be "arbitrary"?
--Guy
∂16-Mar-89 1205 X3J13-mailer Issue: TIME-ZONE-NON-INTEGER, v.1
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 12:03:57 PST
Received: from fafnir.think.com by Think.COM; Thu, 16 Mar 89 14:41:11 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Thu, 16 Mar 89 14:42:22 EST
Received: by verdi.think.com; Thu, 16 Mar 89 14:39:11 EST
Date: Thu, 16 Mar 89 14:39:11 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903161939.AA05061@verdi.think.com>
To: barmar@Think.COM
Cc: masinter.pa@xerox.com, x3J13@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Thu, 16 Mar 89 12:16 EST <19890316171639.5.BARMAR@OCCAM.THINK.COM>
Subject: Issue: TIME-ZONE-NON-INTEGER, v.1
Date: Thu, 16 Mar 89 12:16 EST
From: Barry Margolin <barmar@Think.COM>
Date: 16 Mar 89 07:07 PST
From: masinter.pa@xerox.com
Proposal (TIME-ZONE-NON-INTEGER:ALLOW)
Specify that the time zone part of Decoded Time is a rational number
(either an integer or a ratio).
Just to show you, when I become a billionaire I'll form my own country
and give it an irrational time zone (e in the winter, sqrt(2) in the
summer).
Seriously, is there any particular reason not to allow any non-complex
number as a time zone?
barmar
When you become a billionaire, you'll probably find that
you get a better approximation to e or sqrt(2) with a moby
bignum rational than with a float.
--Quux
∂16-Mar-89 1212 X3J13-mailer Issue: COPY-SYMBOL-PRINT-NAME, v.2
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 12:12:18 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 11:42:46 PST
Date: 16 Mar 89 11:29 PST
From: masinter.pa@Xerox.COM
Subject: Issue: COPY-SYMBOL-PRINT-NAME, v.2
to: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-114246-4951@Xerox>
!
Issue: COPY-SYMBOL-PRINT-NAME
References: COPY-SYMBOL (p. 169)
Category: CLARIFICATION
Edit history: 1-MAR-89, Version 1 by Chapman
15-MAR-89, Version 2 by Chapman
Problem Description:
The description of COPY-SYMBOL states that it "returns a new uninterned
symbol with the same print name as sym (its first argument)". The words
"the same as" are not defined in CLtL. Do they mean EQ, EQUAL, ...?
Proposal (COPY-SYMBOL-PRINT-NAME:EQUAL)
The description of COPY-SYMBOL should read as follows:
"COPY-SYMBOL returns an uninterned
symbol whose print name is STRING= to
the print name of the symbol that is the first argument to COPY-SYMBOL."
Suggested implementation note:
The string should not be copied unnecessarily. In this case, the uninterned
symbol's print name would be EQ to the print name of the argument symbol.
Rationale:
This clarification resolves any possibility of ambiguity.
Current Practice:
Medley did this: the symbol names didn't really have a string header and
some symbol names (the "initial symbols" ) had a different place for
storing the actual characters than symbols created later. Unfortunately,
that means that SYMBOL-NAME has to CONS.
It wasn't so much a problem for Interlisp since most of the "string"
functions in Interlisp will take symbols, but in Common Lisp, it is a
performance hit. Poor design, but there's no reason to require SYMBOL-NAME
to return EQ strings.
In this case, the strings aren't EQ even though the string characters are
shared. (Think of it as strings displaced to a shared area.)
Adoption Cost:
?
Benefits:
Less ambiguity in the specification, and potentially more portable code.
Conversion Cost:
?
Aesthetics:
None.
Discussion:
∂16-Mar-89 1212 X3J13-mailer Issue: COPY-SYMBOL-COPY-PLIST, v.1
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 12:12:12 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 11:27:49 PST
Date: 16 Mar 89 11:27 PST
From: masinter.pa@Xerox.COM
Subject: Issue: COPY-SYMBOL-COPY-PLIST, v.1
To: x3j13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-112749-4871@Xerox>
The only discussion on this issue was whether it was necessary
to clarify (some thought it was) and whether a more general
"copy the list means COPY-LIST" was necessary (probably not.)
There was no controversy on the proposal itself.
!
Issue: COPY-SYMBOL-COPY-PLIST
References: COPY-SYMBOL (p 169), COPY-LIST (p 268), COPY-TREE (p
269).
Category: CLARIFICATION
Edit history: 10-Jan-89, Version 1 by Margolin
Problem Description:
The description of COPY-SYMBOL, where the COPY-PROPS optional argument
is non-NIL, says that a copy of the property list is used as the new
symbol's property list. However, there are several ways in which a list
may be copied, most notably COPY-LIST and COPY-TREE, and the description
doesn't say which mechanism should be used.
Proposal (COPY-SYMBOL-COPY-PLIST:COPY-LIST)
Clarify that when COPY-SYMBOL copies the property list of the symbol, it
is as if (COPY-LIST (SYMBOL-PLIST sym)) were used as the new symbol's
property list.
Rationale:
COPY-LIST is the simplest list-copying primitive. The result of this
copy is that GET returns EQL results for the two symbols until one of
the property lists is altered, but altering either of the property lists
doesn't affect the other. This is current practice in the
implementations I tested, and probably what most users assume.
Current Practice:
Symbolics Genera and Sun Common Lisp currently implement this. I
suspect most others do, too.
Cost to Implementors:
Little or none.
Cost to Users:
None unless they've been assuming some other type of copy.
Benefits:
Less ambiguity.
Aesthetics:
Well, I like it.
∂16-Mar-89 1213 X3J13-mailer
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 12:12:39 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 12:00:57 PST
Date: 16 Mar 89 11:59 PST
From: masinter.pa@Xerox.COM
To: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-120057-5042@Xerox>
I think this is one of the more important issues to consider,
in that it is addresses one of the most frequently noted
performance issues in Common Lisp. We've examined a large number
of proposals and alternatives to allow declaration of dynamic extent
in Common Lisp.
!
Forum: CLEANUP
Issue: DYNAMIC-EXTENT
References: Scope and Extent
Category: ADDITION
Edit history: 27-Jun-88, Version 1 by Pitman (as issue STACK-LET)
15-Nov-88, Version 2 by Pitman (issue renamed, major revision)
11-Jan-89, Version 3 by Masinter (Moon's proposal)
Related-Issues: REST-ARGUMENT-EXTENT, WITH-DYNAMIC-EXTENT
Problem Description:
Sometimes a programmer knows that a particular data structure
will have only dynamic extent. In some implementations, it is
possible to allocate such structures in a way that will make them
easier to reclaim than by general purpose garbage collection
(eg, on the stack or in some temporary area). Currently, however,
there is no way to request the use of such an allocation mechanism.
Proposal (DYNAMIC-EXTENT:NEW-DECLARATION):
Introduce a new declaration called DYNAMIC-EXTENT. The arguments to
this declaration are names of variables. The declaration asserts that
the value which is initially held by the indicated variable will have
dynamic extent. [In the case of an iteration variable, the declaration
asserts that on every iteration, the initial value of that variable
for the iteration will have dynamic extent.]
It is permissible for an implementation to simply ignore this declaration.
In implementations which do not ignore it, the compiler (or interpreter)
is free to make whatever optimizations are appropriate given this
information; the most common optimization is to stack-allocate the
initial value of the object. What data types (if any) can have dynamic
extent will can vary from implementation to implementation.
Since stack allocation of the initial value entails knowing at the
object's creation time that the object can be stack-allocated, it is
not generally useful to declare DYNAMIC-EXTENT for variables for
which have no lexically apparent initial value. For example,
(DEFUN F ()
(LET ((X (LIST 1 2 3)))
(DECLARE (DYNAMIC-EXTENT X))
...))
would permit those compilers which wish to do so to stack-allocate the
list in X. However,
(DEFUN G (X) (DECLARE (DYNAMIC-EXTENT X)) ...)
(DEFUN F () (G (LIST 1 2 3)))
could not typically permit a similar optimization in G because it would
be a modularity violation for the compiler to assume facts about G from
within F. Only an implementation which was willing to be responsible for
recompiling F if G's definition changed incompatibly could stack-allocate
the list argument to G in F.
Other interesting cases are:
(PROCLAIM '(INLINE G))
(DEFUN G (X) (DECLARE (DYNAMIC-EXTENT X)) ...)
(DEFUN F () (G (LIST 1 2 3)))
and (DEFUN F ()
(FLET ((G (X) (DECLARE (DYNAMIC-EXTENT X)) ...))
(G (LIST 1 2 3))))
where some compilers might realize the optimization was possible and others
might not.
An interesting variant of this is the so-called `stack allocated rest list'
which can be achieved (in implementations supporting the optimization) by:
(DEFUN F (&REST X)
(DECLARE (DYNAMIC-EXTENT X))
...)
Note here that although the initial value of X is not explicit, the F
function is responsible for assembling the list X from the passed arguments,
so the F function can be optimized by the compiler to construct a
stack-allocated list instead of a heap-allocated list in implementations
which support such.
The meaning of a dynamic extent declaration is that execution of the
forms in the scope of the declaration will not "save" any "proper part"
of the initial value of the declared variable. To "save" an object
means to cause a reference to that object to be accessible outside the
dynamic extent of the form at the beginning of whose body the
declaration appears. An object can be "saved" by storing it with a
side-effecting operation and not replacing it with a different value
before the end of the dynamic extent, by using it as a component of a
freshly-allocated object that is itself "saved," by capturing it in a
function closure that is itself "saved," by returning it as a value, or
by transmitting it outside the dynamic extent with THROW. A "proper
part" of an object A is any object that is accessible at the beginning
of the scope of the declaration -only- by applying a function to A or to
a "proper part" of A. This means that any objects freshly allocated
during the construction of the initial value of the declared variable,
and not "saved" during the construction of that value, are "proper
parts" and can be allocated on a stack.
Examples:
In
(LET ((X (LIST 'A1 'B1 'C1))
(Y (CONS 'A2 (CONS 'B2 (CONS 'C2 NIL)))))
(DECLARE (DYNAMIC-EXTENT X Y))
...)
The "proper parts" of X are three conses, and the "proper parts" of Y
are three other conses. None of the symbols A1, B1, C1, A2, B2, C2, or
NIL is a "proper part" of X or Y. However, if a freshly allocated
uninterned symbol had been used, it would have been a "proper part."
- - - - - - - -
(DOTIMES (I N)
(DECLARE (DYNAMIC-EXTENT I))
This is particularly instructive. Since I is an integer by the
definition of DOTIMES, but EQ and EQL are not necessarily equivalent for
integers, what are the "proper parts" of I, which this declaration
requires the body of the DOTIMES not to "save"? If the value of I is 3,
and the body does (SETQ FOO 3), is that an error? The answer is no, but
the interesting thing is that it depends on the implementation-dependent
behavior of EQ on numbers. In an implementation where EQ and EQL are
equivalent for 3, then 3 is not a "proper part" because (EQ I (+ 2 1))
is true, and therefore there is another way to access the object besides
going through I. On the other hand, in an implementation where EQ and
EQL are not equivalent for 3, then the particular 3 that is the value of
I is a "proper part", but any other 3 is not. Thus (SETQ FOO 3) is valid
but (SETQ FOO I) is erroneous. Since (SETQ FOO I) is erroneous in some
implementations, it is erroneous in all portable programs, but some other
implementations may not be able to detect the error.
- - - - - - - -
(LET ((X (LIST 1 2 3)))
(DECLARE (DYNAMIC-EXTENT X))
(PRINT X)
NIL)
PRINT does not "save" any part of its input.
This prints (1 2 3)
- - - - - - - -
(DO ((L (LIST-ALL-PACKAGES) (CDR L)))
((NULL L))
(DECLARE (DYNAMIC-EXTENT L))
(PRINT (CAR L)))
prints all packages; none of the newly-allocated list structures are saved.
- - - - - - - -
(DEFUN ADD (&REST X) (DECLARE (DYNAMIC-EXTENT X)) (APPLY #'+ X))
(ADD 1 2 3) => 6
I.e., useful way to declare that &REST lists have dynamic extent
- - - - - - - -
(DEFUN ZAP (X Y Z)
(DO ((L (LIST X Y Z) (CDR L)))
((NULL L))
(DECLARE (DYNAMIC-EXTENT L))
(PRIN1 (CAR L))))
(ZAP 1 2 3)
prints 123
- - - - - - - -
(DEFUN ZAP (N M)
;; Computes (RANDOM (+ M 1)) at relative speed of roughly O(N).
;; It may be slow, but with a good compiler at least it
;; doesn't waste much heap storage. :-)
(LET ((A (MAKE-ARRAY N)))
(DECLARE (DYNAMIC-EXTENT A))
(DOTIMES (I N)
(DECLARE (DYNAMIC-EXTENT I))
(SETF (AREF A I) (RANDOM (+ I 1))))
(AREF A M)))
(< (ZAP 5 3) 3) => T
- - - - - - - -
The following are in error, since the value of X is used outside of its
extent:
(LENGTH (LIST (LET ((X (LIST 1 2 3))) (DECLARE (DYNAMIC-EXTENT X)) X)))
(PROGN (LET ((X (LIST 1 2 3))) (DECLARE (DYNAMIC-EXTENT X)) X)
NIL)
- - - - - - - -
Rationale:
This permits a programmer to offer advice to an implementation about
what may be stack-allocated for efficiency.
It may be difficult or impossible for a compiler to infer this
same information statically.
Since a number of implementations offer this capability and there
is demand from users for access to the capability, this ``codifies
existing practice.''
Because this approach is purely lexical, it does not interact badly with
other programs in the way that the macro WITH-DYNAMIC-EXTENT (see issue
by same name) would.
Current Practice:
Symbolics Genera and Symbolics Cloe offer stack allocation, though not
in this strategy.
[KMP thinks that] Lucid supports the proposal.
Cost to Implementors:
No cost is forced since implementations are permitted to simply
ignore the DYNAMIC-EXTENT declaration.
Cost to Users:
None. This change is upward compatible.
There may be some hidden costs to debugging using this declaration (or any
feature which permits the user to access dynamic extent objects without
the compiler proving that they are appropriate). If the user misdeclares
something and returns a pointer into the stack (or stores it in the heap),
an undefined situation may result and the integrity of the Lisp storage
mechanism may be compromised. Debugging these situations may be tricky,
but users who have asked for this feature have indicated a willingness
to deal with such costs. Nevertheless, the perils should be clearly
documented and casual users should not be encouraged to use this
declaration.
Cost of Non-Adoption:
Some portable code would be forced to run more slowly (due to
GC overhead), or to use non-portable language features.
Benefits:
The cost of non-adoption is avoided.
Aesthetics:
This declaration allows a fairly low level optimization to work
by asking the user to provide only very high level information.
The alternatives (sharpsign conditionals, some of which may
lead to more bit-picky abstractions) are far less aesthetic.
Discussion:
A previous version of this proposal suggested primitives STACK-LET
and STACK-LET*. Consensus was that the more general declaration facility
would be more popular.
Pitman supports the DYNAMIC-EXTENT:NEW-DECLARATION.
Actually, a blurry issue is whether
(LENGTH (LIST (LET ((X (LIST 1 2 3))) (DECLARE (DYNAMIC-EXTENT X)) X)))
=> 1
is well-defined. I refer to these stack-allocated things as being invalid
return values, but in fact we might want to say that they're ok to return
but that you just can't do any serious operations on them (ie, you can't
expect them to still be lists, etc.) Can anyone imagine a pointer into
unallocated stack causing problems for their GC? If so, we could be more
clear on this point.
The examples are tricky:
"I hope no one misreads the above as an argument that my proposal is too
complicated, since it does not derive at all from my proposal, but only
from the way Common Lisp works."
!
Additional comments:
... I really like this rewrite a lot. It's quite
clever in the way it presents things in order to get additional flexibility.
However, I do have a few comments I'd like to see addressed before this
gets to a vote...
* I like the concept "proper part" a lot but I don't like the name.
The term "proper" for proper lists has to do with well-formed-ness
and in this context you're suggesting an incompatible meaning which
is confusing.
I suggest instead a term like "internal", "intrinsic", "private",
"unshared", etc.
[The concept of "unshared" makes me immediately scared about the
whole quote-may-copy morass, but I don't have time to think through
right now whether that's an issue that needs further clarification
or if it's just a red herring.]
* I like the concept of "saved" but it has the problem that it isn't
easy to bring up "out of context" since "save" has a lot of connotations.
If it were possible to come up with a more unique term, I think it
would help in lunch table conversations when people start getting
screwed by things that were `unintentionally saved' and others can't
figure out what they mean out of context.
* I think your list of definitions for saved is pretty good, but I'd
still like to see an abstract definition, and then the concrete cases
listed beneath it. That way, we are protected from weird unintentional
interpretations if someone discovers that the set was not exhaustive
and needs to include their new case under the abstract description
because the concrete list doesn't accomodate things.
* What about things like:
(DEFUN FOO (&REST X)
(DECLARE (DYNAMIC-EXTENT X))
(MAPL #'PRINT X)
T)
Genera's Dynamic Windows (DW) had bugs in its first release because the
window history recorded the object which was printed. Put another
way, PRINT did unexpected "saving" on some streams. The situation with
DW was treated as a bug and now DW correctly detects stack-allocated
things and does not try to save them, so this would work now.
However, it still raises the question of whether we should define
per-function for every CL function whether any of the arguments is
permitted to be "saved" so that CL programs don't get any funny surprises.
If we don't, it ends up being implementor's discretion how to resolve
cases like this, and everyone might not agree that all cases are as
obvious as this one was.
- - - - - - -
re: However, it still raises the question of whether we should define
per-function for every CL function whether any of the arguments is
permitted to be "saved" so that CL programs don't get any funny surprises.
If we don't, it ends up being implementor's discretion how to resolve
cases like this, and everyone might not agree that all cases are as
obvious as this one was.
PDP10 MacLisp had a similar problem w.r.t pdlnums. That is why
"identity" functions were so troublsome for it -- in order to
return a guaranteed safe value, it typically had to copy it's
pdlnum argument, thereby making some cases of "fast arithmetic"
code much worse than interpreted code! [Remember PRINT in MacLisp?
it returns T rather than it's argument for just this reason.]
It is necessary for an optimizing compiler to know something about
what happens to the data it passes along to "system" functions; for
example, it could assume that GET doesn't clobber the list given
to it, nor does it retain pointers to any part of it [what was the
terminology in the revised proposal? "saved"? and "proper part"?]
The issue LISP-SYMBOL-REDEFINITION might help here, in that an
implementation's compilers could depend upon it's own internal
database. But it wouldn't hurt at all to have some of these
requirements "up front" in the standard.
∂16-Mar-89 1212 X3J13-mailer *DRAFT* Issue: DESTRUCTURING-BIND, v.2
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 12:12:27 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 11:49:11 PST
Date: 16 Mar 89 11:46 PST
From: masinter.pa@Xerox.COM
Subject: *DRAFT* Issue: DESTRUCTURING-BIND, v.2
to: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-114911-4982@Xerox>
This issue is draft; there will hopefully be a new version before
the meeting.
The discussion centers around what lambda-list keywords should be
allowed.
&ENVIRONMENT:
everybody says disallow
&WHOLE:
Moon said allow (the second time.)
NIL:
Moon says allow as a way of ignoring.
KMP says OK, maybe in other places too.
Discussion of IGNORE led to new issue.
&BODY:
KMP makes case for disallowing, but says
allow.
There was some additional discussion that resulted in the
related issues of DEFMACRO-LAMBDA-LIST and IGNORE-VARIABLE.
I'd be happy with a proposal that said NIL is ignored,
&WHOLE and &BODY are allowed, and that &ENVIRONMENT
is disallowed. I'd like to make sure it was consistent
with LOOP.
!
Issue: DESTRUCTURING-BIND
Forum: Cleanup
References: DEFMACRO (CLtL pp145-151),
The LOOP Facility (X3J13/89-004)
Category: ADDITION
Edit history: 24-Jan-89, Version 1 by Pitman
25-Jan-89, Version 2 by Pitman
Status: For Internal Discussion
Problem Description:
Common Lisp programmers have frequently complained that the
destructuring facility used by DEFMACRO is not made available
for use in ordinary programming situations involving list data.
The presence of a destructuring facility in the recently adopted
LOOP facility will be likely to make the absence of a separable
destructuring facility all the more apparent.
Prior to the introduction of LET into Maclisp, many people wrote
their own LET macros. A popular expansion was in terms of a DO
which did not iterate. eg,
(LET ((A 3)) (+ A A)) ==> (DO ((A 3)) () (RETURN (+ A A)))
While this practice `worked,' it was not perspicuous and contributed
substantially to non-readability: not only were the macros hard to
understand, but the surface interface itself was not standardized
and varied in subtle ways. For example, some LET macros allowed GO
statements while others did not.
There is now considerable danger that a lot of people will write
DESTRUCTURING-BIND variants in terms of a LOOP expression that
immediately returns.
(DESTRUCTURING-BIND ((A B) C) (FOO) (LIST A B C))
==> (LOOP FOR ((A B) C) ON (FOO) DO (RETURN (LIST A B C)))
Since the destructuring offered by LOOP is different in subtle ways
from the destructuring offered by DESTRUCTURING-BIND in implementations
offering that primitive natively, gratuitous headaches could result.
Proposal (DESTRUCTURING-BIND:NEW-MACRO):
Provide a macro called DESTRUCTURING-BIND which behaves like the
destructuring bind in DEFMACRO. Specifically...
DESTRUCTURING-BIND lambda-list expression {decl|doc}* {form}* [Macro]
Binds the variables specified in LAMBDA-LIST to the corresponding
values in the tree structure resulting from evaluating EXPRESSION,
then evaluates the FORMS in the body.
Anywhere in the LAMBDA-LIST where a parameter name may appear, and
where ordinary lambda-list syntax (as described in CLtL section 5.2.2)
does not otherwise allow a list, a lambda-list may appear in place of
the parameter name. When this is done, then the argument form that
would match the parameter is treated as a (possibly dotted) list, to
be used as an argument forms list for satisfying the parameters in
the embedded lambda-list.
If any of the lambda list keywords &OPTIONAL, &REST, &KEY,
&ALLOW-OTHER-KEYS and &AUX appears in the lambda list, it is treated
as with any other lambda-list.
If the lambda list keyword &BODY appears, it is treated as a synonym
for &REST.
If the lambda list keyword &WHOLE appears, it must be followed by a
single variable that is bound to the entire expression at the current
level. &WHOLE and the following variable should appear first in the
list, before any other parameter or lambda-list keyword.
It is also permissible for any level of the LAMBDA-LIST to be dotted,
ending in a parameter name. This situation is treaed exactly as if
the aprameter name that ends the list had appeared preceded by &REST
in a proper list. For example, the notation (X Y . Z) is equivalent
to (X Y &REST Z).
If the result of evaluating the expression does not match the
destructuring pattern, the consequences are undefined. Implementations
are not required to signal an error in this case, but neither are they
permitted to extend the behavior by defining it to be harmless.
Clarify that the destructuring done by LOOP does not permit the use of
any lambda-list-keywords. Further clarify that in LOOP, proper lists
are implicitly `&REST var' (where the non-use of var is quietly ignored).
Hence, it is permissible to have:
(LOOP FOR (X Y) ON '(A B C D) COLLECT (CONS X Y)) => ((A . B) (C . D))
but it is not permissible to have:
(DESTRUCTURING-BIND (X Y) '(A B C D) (CONS X Y))
since the pattern does not match. One must instead write:
(DESTRUCTURING-BIND (X Y &REST Z) '(A B C D)
(DECLARE (IGNORE Z))
(CONS X Y))
Test Case:
(DEFUN IOTA (N) (LOOP FOR I FROM 1 TO N COLLECT I)) ;helper
(DESTRUCTURING-BIND ((A &OPTIONAL (B 'BEE)) ONE TWO THREE)
`((ALPHA) ,@(IOTA 3))
(LIST A B THREE TWO ONE))
=> (ALPHA BEE 3 2 1)
Rationale:
The proposal directly addresses the stated problem, and is current practice
in numerous implementations. Our charter effectively dictates that where
feasible we should try to head off the widespread development of uselessly
different variants of commonplace tools.
Current Practice:
Symbolics Genera, Envos Medley, TI Explorer, and Lucid CL all offer
DESTRUCTURING-BIND, though the details vary slightly.
The DESTRUCTURING-BIND offered by Symbolics Genera signals an error if
the pattern is not matched. The TI Explorer version does not.
Cost to Implementors:
Very small. In most cases, it's a matter of renaming and/or exporting an
already existing symbol. In a few cases, a very small amount of
`program interface' code would have to be written.
Cost to Users:
None. This is an upward compatible change.
Cost of Non-Adoption:
Loss of the Benefits and Aesthetics cited below.
Benefits:
Users will get a powerful feature they have asked for on many occassions.
In implementations which `autoload' code, it would be better for this
support to be separable so that people could do DESTRUCTURING-BIND
without demand loading all other LOOP support.
Aesthetics:
Defining this macro centrally for the Common Lisp community will reduce
subtle deviations, which will in turn have positive aesthetic impact.
Discussion:
JonL observes that although LOOP does destructuring, it can't directly
make use of the DESTRUCTURING-BIND interface suggested here.
Pitman and Gray think a facility of this sort is a good idea, though
obviously the details may still need a little fleshing out before the
proposal is ready for vote.
To date, the excuse for not satisfying this request has been a
religious war between factions who want to destructure lists by
writing
(DESTRUCTURING-BIND (var1 var2 var3) exp . body)
and those who want to destructure lists by writing
(DESTRUCTURING-BIND (LIST var1 var2 var3) exp . body)
The advantage of the former approach is that it is notationally
concise for the common case of destructuring a list. The disadvantage
is that it is not extensible to accomodate abstract kinds of
destructuring.
The advantage of the latter approach is that it allows interesting
extensions that accomodate data-hiding, such as:
(DEFMACRO MAKE-FOO (&REST ELEMENTS) `(LIST ,@ELEMENTS))
(DESTRUCTURING-BIND (MAKE-FOO var1 var2 var3) exp . body)
and later the ability to change the representation of a FOO without
updating the associated binding forms. The disadvantage is that it
is more verbose in the common case of destructuring a list, and still
even more verbose for nested lists.
Although destructuring has always existed in DEFMACRO, this has not
been adequate precedence for deciding the outcome of the religious war
because DEFMACRO only needs to destructure programs, and programs are
generally made up only of lists -- not arbitrary user-defined abstract
data types.
∂16-Mar-89 1221 X3J13-mailer Issue DESCRIBE-UNDERSPECIFIED, v.1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89 12:20:58 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558750; Thu 16-Mar-89 15:18:32 EST
Date: Thu, 16 Mar 89 15:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue DESCRIBE-UNDERSPECIFIED, v.1
To: masinter.pa@Xerox.COM, Kim A. Barrett <IIM@ECLA.USC.EDU>
cc: x3j13@SAIL.STANFORD.EDU
In-Reply-To: <890316-082029-3881@Xerox>
Message-ID: <19890316201824.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
I think this is unnecessary, but I do not strongly oppose it.
The proposed division of labor between the DESCRIBE function and
the DESCRIBE-OBEJCT generic function could be implemented by
an :AROUND method for the existing DESCRIBE generic function.
The claim that binding *STANDARD-OUTPUT* is dangerous in the
presence of interrupts is false, since many things bind
*STANDARD-OUTPUT* and any reasonable interactive interrupt
handler must rebind the standard streams, the print control
variables, etc.
I don't strongly oppose this since it might be worthwhile just
for the symmetry with the PRINT-OBJECT generic function.
∂16-Mar-89 1241 X3J13-mailer Issue DYNAMIC-EXTENT: a remark
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 12:41:00 PST
Received: from fafnir.think.com by Think.COM; Thu, 16 Mar 89 15:36:50 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Thu, 16 Mar 89 15:38:04 EST
Received: by verdi.think.com; Thu, 16 Mar 89 15:34:53 EST
Date: Thu, 16 Mar 89 15:34:53 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903162034.AA05881@verdi.think.com>
To: masinter.pa@xerox.com
Cc: X3J13@sail.stanford.edu
In-Reply-To: masinter.pa@xerox.com's message of 16 Mar 89 11:59 PST <890316-120057-5042@Xerox>
Subject: Issue DYNAMIC-EXTENT: a remark
This is the last paragraph of the proposal DYNAMIC-EXTENT:NEW-DECLARATION:
The meaning of a dynamic extent declaration is that execution of the
forms in the scope of the declaration will not "save" any "proper part"
of the initial value of the declared variable. To "save" an object
means to cause a reference to that object to be accessible outside the
dynamic extent of the form at the beginning of whose body the
declaration appears. An object can be "saved" by storing it with a
side-effecting operation and not replacing it with a different value
before the end of the dynamic extent, by using it as a component of a
freshly-allocated object that is itself "saved," by capturing it in a
function closure that is itself "saved," by returning it as a value, or
by transmitting it outside the dynamic extent with THROW. A "proper
part" of an object A is any object that is accessible at the beginning
of the scope of the declaration -only- by applying a function to A or to
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
a "proper part" of A. This means that any objects freshly allocated
during the construction of the initial value of the declared variable,
and not "saved" during the construction of that value, are "proper
parts" and can be allocated on a stack.
I believe that the words indicated above should be replaced by
"the extent of the binding for which the delaration was made".
The reference appears to be to a point in time. Scopes are in space;
the beginning of a scope is a character position in the text (or
something like that). Extents are in time. Is this what you meant?
--Conan the Pedantrian (a.k.a. Guy)
∂16-Mar-89 1436 X3J13-mailer Fatal vesus Harmless
To: x3j13@SAIL.Stanford.EDU
CC: cl-editorial@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
This is my last attempt at making my argument. I don't think there is much
else I can say to persuade you.
I wrote:
``The definition of fatal puts no time constraints on the fatality. Therefore,
neither does its negation.''
Let's define the term ``win'' to mean ``doesn't crash or abnormally
terminate''; basically, it is the bad case that the definition of
``fatal'' talks about. Let ``lose'' mean ``not win.''
Here are two partially formal definitions of ``fatal'' and ``harmless.''
The program P has consequences that are fatal if there
exists a sequence of conforming programs, P1,...,Pj,Pj+1,...,Pn, where
(progn P1...Pn) wins, but (progn P1...Pj P Pj+1...Pn) loses.
That is, the execution of P eventually leads to fatality in some program.
The program P has consequences that are harmless if
for all sequences of conforming programs, P1,...,Pj,Pj+1,...,Pn, where
(progn P1...Pn) wins, (progn P1...Pj P Pj+1...Pn) also wins.
That is, the execution of P never leads to fatality in any program.
There might be an infinite amount of hair to make this precise, but that's
the idea. And, there is some question about how different we allow the
behavior of the programs with P to be from the behavior of the programs
without P. (The language of the definitions of these terms are meant to
warn people to beware that behavior is in jeopardy.) But, the terms are
related by a negation with respect to the degree to which they are
well-defined.
I think part of the problem of understanding comes from the question of
side effects noticeable to conforming programs. A program with harmless
consequences can have side effects; notice our partly formal definition
doesn't say anything about what the programs do.
We all believe harmless a garbage collector that moves objects from place
to place where the movement is unnoticeable by conforming programs. Probably
most of us believe harmless a garbage collector whose progress is displayed.
I think none of us believes harmless a garbage collector that sets to
NIL all property lists of symbols in the USER package.
I think most of use believe harmful a garbage collector that changes the
order of properties on property lists.
However, consider an implementation of Common Lisp that uses a very hairy
representation for property-list lists. These lists have the feature that
sometimes the garbage collector will re-order their properties according
to some LRU bits to aid performance. Of course, through extreme hair, the
GC won't change the order if some piece of the property list is stored
somewhere other than the property list itself. Think of it as an
optimization that is conservatively performed.
Nowhere does the CL specification state that the order of properties
remains constant if the property list is not explicitly altered. Do those
of us who believed harmful the GC that changed property list order believe
this GC harmful? Or did some of us change our votes?
Suppose we alter the definition of symbol-plist from this:
``This returns *the* list the contains the property pairs of <symbol>;
the contents of the property-list cell are *extracted* and returned.''
to this:
``This returns *a* list the contains the property pairs of <symbol>;
the contents of the property-list cell are *copied* and returned.''
Now does the order-changing GC seem more harmless? It certainly has
less transparent behavior.
Suppose we explicitly specified that the order of properties on a property
list could change from time to time, possibly by GC actions. We have
defined the GC to be non-transparent, but is it harmless?
The sense of the definitions come from the partially formal definitions.
I think these definitions are pesuasive regarding the usefulness of a
term like ``harmless.''
I believe those definitions are difficult to make formal without some
very detailed computational or semantic model. The series of strange
GC behaviors with respect to property lists should make us leery of
making these definitions too precise at the expense of deciding these
cases one way when in five years we will wish we could decide them
the other way.
Specifications such as the one we are writing are communications
among people, and therefore absolute precision is impossible without
overspecification.
-rpg-
∂16-Mar-89 1418 X3J13-mailer Issue DYNAMIC-EXTENT: a remark
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89 14:18:09 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558915; Thu 16-Mar-89 17:15:26 EST
Date: Thu, 16 Mar 89 17:15 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue DYNAMIC-EXTENT: a remark
To: Guy Steele <gls@Think.COM>
cc: masinter.pa@xerox.com, X3J13@sail.stanford.edu
In-Reply-To: <8903162034.AA05881@verdi.think.com>
Message-ID: <19890316221519.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 16 Mar 89 15:34:53 EST
From: Guy Steele <gls@Think.COM>
A "proper
part" of an object A is any object that is accessible at the beginning
of the scope of the declaration -only- by applying a function to A or to
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
a "proper part" of A. This means that any objects freshly allocated
during the construction of the initial value of the declared variable,
and not "saved" during the construction of that value, are "proper
parts" and can be allocated on a stack.
I believe that the words indicated above should be replaced by
"the extent of the binding for which the delaration was made".
That would change the meaning, since the declaration might not be attached
to a binding.
The reference appears to be to a point in time. Scopes are in space;
the beginning of a scope is a character position in the text (or
something like that). Extents are in time. Is this what you meant?
You're right that there is something wrong with this wording. How about
if it said "at the beginning of execution of the forms in the scope of
the declaration"? Do declarations have extents? If so, could it say
"at the beginning of the extent of the declaration"?
∂16-Mar-89 1424 X3J13-mailer Issue: TIME-ZONE-NON-INTEGER, v.1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89 14:23:49 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558923; Thu 16-Mar-89 17:20:36 EST
Date: Thu, 16 Mar 89 17:20 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: TIME-ZONE-NON-INTEGER, v.1
To: barmar@Think.COM
cc: Guy Steele <gls@Think.COM>, masinter.pa@xerox.com, x3J13@sail.stanford.edu
In-Reply-To: <8903161939.AA05061@verdi.think.com>
Message-ID: <19890316222034.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 16 Mar 89 14:39:11 EST
From: Guy Steele <gls@Think.COM>
Date: Thu, 16 Mar 89 12:16 EST
From: Barry Margolin <barmar@Think.COM>
Date: 16 Mar 89 07:07 PST
From: masinter.pa@xerox.com
Proposal (TIME-ZONE-NON-INTEGER:ALLOW)
Specify that the time zone part of Decoded Time is a rational number
(either an integer or a ratio).
Just to show you, when I become a billionaire I'll form my own country
and give it an irrational time zone (e in the winter, sqrt(2) in the
summer).
When you become a billionaire, you'll probably find that
you get a better approximation to e or sqrt(2) with a moby
bignum rational than with a float.
As a billionaire, you'll be able to afford to do all your processing
with indefinite-precision exact arithmetic.
Does Guy have inside information on when Barry will become a billionaire?
∂16-Mar-89 1443 CL-Compiler-mailer Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89 14:43:02 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558959; Thu 16-Mar-89 17:39:16 EST
Date: Thu, 16 Mar 89 17:39 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
To: Barry Margolin <barmar@FAFNIR.THINK.COM>
cc: masinter.pa@xerox.com, cl-compiler@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: <19890316173142.7.BARMAR@OCCAM.THINK.COM>
Message-ID: <19890316223916.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 16 Mar 89 12:31 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
I'll just reiterate something I said at one of the meetings. One
portable use I can think of for the COMPILED-FUNCTION type is as a
declaration to allow compiler optimization. If a function knows (or
requires) that a parameter is a compiled function it can declare that
and the implementation may be able to optimize the FUNCALL better.
But as someone said the last time this suggestion was brought up, if
there is no portable meaning of the COMPILED-FUNCTION type and no
portable way to create an object of that type, no useful correct program
can contain this declaration.
Another thing I just thought of is something like:
(when (typep f '(and function (not compiled-function)))
(setq f (compile nil f)))
This doesn't actually work because COMPILE isn't required to accept
lexical closures
You just glimpsed the tip of the iceberg.
∂16-Mar-89 1354 X3J13-mailer Issue: DYNAMIC-EXTENT
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 13:54:21 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Thu, 16 Mar 89 16:49:45 EST
Date: Thu, 16 Mar 89 16:50 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: DYNAMIC-EXTENT
To: masinter.pa@xerox.com
Cc: X3J13@sail.stanford.edu
In-Reply-To: <890316-120057-5042@Xerox>
Message-Id: <19890316215008.1.BARMAR@OCCAM.THINK.COM>
re: However, it still raises the question of whether we should define
per-function for every CL function whether any of the arguments is
permitted to be "saved" so that CL programs don't get any funny surprises.
If we don't, it ends up being implementor's discretion how to resolve
cases like this, and everyone might not agree that all cases are as
obvious as this one was.
...
It is necessary for an optimizing compiler to know something about
what happens to the data it passes along to "system" functions; for
example, it could assume that GET doesn't clobber the list given
to it, nor does it retain pointers to any part of it [what was the
terminology in the revised proposal? "saved"? and "proper part"?]
The issue LISP-SYMBOL-REDEFINITION might help here, in that an
implementation's compilers could depend upon it's own internal
database. But it wouldn't hurt at all to have some of these
requirements "up front" in the standard.
I don't think that solves the problem. Yes, in a system where PRINT
saves its argument the compiler could detect that in
(defun print-em (&rest stuff)
(declare (dynamic-extent stuff))
(print stuff))
the declaration is obviously in error and may be ignored (or it might
generate a warning). In the case of Genera Dynamic Windows, whether
PRINT saves is actually an attribute of the stream, so it is
questionable whether the compiler should override the declaration
(perhaps the programmer knows that the function will only be called with
*STANDARD-OUTPUT* bound to a non-saving stream). Also, what about the
function
(defun process-em (&rest stuff)
(declare (dynamic-extent stuff))
(frobnicate stuff))
If FROBNICATE hasn't been written yet the compiler has no way of
knowing whether it calls any system functions that save the argument.
I think that if we really want this declaration (and I'd like to see it
included, as it is the right compromise for a long-standing problem) we
MUST say something about passing dynamic data to standard functions. I
think it would be sufficient to say that if the standard doesn't specify
that an argument must be saved then a dynamic object must be acceptable.
In other words, if a user reading the standard can't infer that an
argument will be saved then a conforming program may pass dynamic data
in that argument. This means that PRINT must accept a dynamic object,
and it is the implementation's responsibility to solve the potential
problems if it normally saves what PRINT prints.
barmar
∂16-Mar-89 1356 CL-Compiler-mailer Issue SAFE-CODE, version 1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89 13:56:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558883; Thu 16-Mar-89 16:53:42 EST
Date: Thu, 16 Mar 89 16:53 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue SAFE-CODE, version 1
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>, masinter.pa@Xerox.COM
cc: cl-compiler@SAIL.Stanford.EDU, x3j13@SAIL.Stanford.EDU
In-Reply-To: <svXEG@SAIL.Stanford.EDU>,
<890316-070317-3708@Xerox>,
<1avs40@SAIL.Stanford.EDU>,
<19890314214907.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890316215335.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Either "nonsafe code" or "code not declared safe" has better connotations
for me than "unsafe code." I don't really want to get too deeply involved
in choosing the terminology here (if I did, I would be on the editorial
committee), I only wanted to point out that the word used in version 1
of the proposal had an unwanted connotation for me.
∂16-Mar-89 1551 X3J13-mailer Issue: COERCE-INCOMPLETE (Version 3)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 15:51:26 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Thu, 16 Mar 89 17:59:11 EST
Date: Thu, 16 Mar 89 18:00 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: masinter.pa@xerox.com
Cc: x3j13@sail.stanford.edu
In-Reply-To: <890316-095901-4371@Xerox>
Message-Id: <19890316230020.6.BARMAR@OCCAM.THINK.COM>
There's an inconsistency in the names of the proposals. In the Proposal
sections, the two proposals are named LIMITED-ARBITRARY-EXTENSION and
DEPRECATE. But in some other sections they are called COERCE and
DEPRECATE.
Problem with DEPRECATE: Didn't we specify that the way to convert a
lambda expression into a function object is to use (COERCE x 'FUNCTION)?
Or did we also define a new function that does this?
barmar
∂16-Mar-89 1603 X3J13-mailer *DRAFT* Issue: DESTRUCTURING-BIND, v.2
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 16:02:40 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Thu, 16 Mar 89 17:45:15 EST
Date: Thu, 16 Mar 89 17:46 EST
From: Barry Margolin <barmar@Think.COM>
Subject: *DRAFT* Issue: DESTRUCTURING-BIND, v.2
To: masinter.pa@xerox.com
Cc: X3J13@sail.stanford.edu
In-Reply-To: <890316-114911-4982@Xerox>
Message-Id: <19890316224608.4.BARMAR@OCCAM.THINK.COM>
Date: 16 Mar 89 11:46 PST
From: masinter.pa@xerox.com
Current Practice:
The DESTRUCTURING-BIND offered by Symbolics Genera signals an error if
the pattern is not matched. The TI Explorer version does not.
Actually, Genera offers TWO versions of DESTRUCTURING-BIND:
SYMBOLICS-COMMON-LISP:DESTRUCTURING-BIND and
ZETALISP:DESTRUCTURING-BIND. The former signals an error, while the
latter does not (it's probably very similar to the Explorer version,
since they are genetically closer).
barmar
∂16-Mar-89 1726 X3J13-mailer Issue: MAKE-STRING-FILL-POINTER (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 17:25:54 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 16:55:22 PST
Date: 16 Mar 89 16:49 PST
From: masinter.pa@Xerox.COM
Subject: Issue: MAKE-STRING-FILL-POINTER (Version 1)
to: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-165522-6151@Xerox>
The discussion on this issue pointed out that it would
extend the range of MAKE-STRING so that it was no
longer restricted to return a SIMPLE-STRING, which
might break some type-inference.
!
Issue: MAKE-STRING-FILL-POINTER
References: CLtL p.302
Related issues: none that I know of
Category: ADDITION
Edit history: Version 1, 20-Oct-88, by Moon, for discussion
Problem description:
Once again I lost because I expected to be able to use MAKE-STRING
to create a string with a fill-pointer, and I couldn't. I had to use
a more long-winded MAKE-ARRAY call instead.
Proposal (MAKE-STRING-FILL-POINTER:ALLOW):
Give MAKE-STRING a :FILL-POINTER argument, with the same syntax and
semantics as the :FILL-POINTER argument to MAKE-ARRAY.
Examples:
(make-string 80 :fill-pointer 0)
Test Cases:
See examples.
Rationale:
I frequently expect it to be allowed and am surprised when it's not.
Current practice:
I know of no implementations that support this.
Cost to Implementors:
5 cents.
Cost to Users:
none
Cost of non-adoption:
none
Performance impact:
none
Benefits:
Increased language consistency.
Esthetics:
Increased language consistency.
Discussion:
Other MAKE-ARRAY options that one might want to allow, but are
not already allowed or proposed, are :INITIAL-CONTENTS, :ADJUSTABLE,
:DISPLACED-TO, and :DISPLACED-INDEX-OFFSET. A strong case could be
made for :ADJUSTABLE (I use an implementation where it doesn't matter,
so I don't care about that), I don't think anyone would care about the
other three.
∂16-Mar-89 1746 X3J13-mailer Issue: COERCE-INCOMPLETE (Version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89 17:45:59 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 559088; Thu 16-Mar-89 19:18:34 EST
Date: Thu, 16 Mar 89 19:18 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: barmar@Think.COM
cc: masinter.pa@xerox.com, x3j13@sail.stanford.edu
In-Reply-To: <19890316230020.6.BARMAR@OCCAM.THINK.COM>
Message-ID: <890316191820.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Thu, 16 Mar 89 18:00 EST
From: Barry Margolin <barmar@Think.COM>
...
Problem with DEPRECATE: Didn't we specify that the way to convert a
lambda expression into a function object is to use (COERCE x 'FUNCTION)?
Or did we also define a new function that does this?
Re-read FUNCTION-TYPE. The thing Beckerle really wanted and finally
got (over my objection) was that COERCE did nothing `hard' ... What
it ended up being able to be do can be expressed by #'IDENTITY and
#'SYMBOL-FUNCTION.
(COERCE x 'FUNCTION) ==
(ETYPECASE X
(SYMBOL (SYMBOL-VALUE X))
(FUNCTION X))
I don't really think anything more needs to be provided, even if we
DEPRECATE coerce.
∂16-Mar-89 1745 X3J13-mailer Issue: EXTRA-RETURN-VALUES
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 16 Mar 89 17:45:24 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
id AA18011; Thu, 16 Mar 89 00:34:36 PST
Message-Id: <8903160834.AA18011@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
for x3j13@sail.stanford.edu; id AA18011; Thu, 16 Mar 89 00:34:36 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 16 Mar 89 03:24
To: x3j13@sail.stanford.edu
Subject: Issue: EXTRA-RETURN-VALUES
Issue: EXTRA-RETURN-VALUES
References: Chapter 1, Section 1.5, Working draft of standard
Category: Clarification
Edit history: 8-JAN-89, Version 1 by Masinter
3-FEB-89, Version 2 by Chapman
10-MAR-89, Version 3 by Chapman
Problem: Is it OK to return extra values from Common Lisp functions?
Proposal: EXTRA-RETURN-VALUES:NO
A function that is specified by the standard must return EXACTLY the number
of return values specified by the standard.
Rationale:
The reason is that
additional arguments are visible to otherwise portable programs. For
instance, (multiple-value-call #'cons (floor x y)) looks portable, but it
will try to pass the wrong number of arguments to CONS if FLOOR returns an
extra value.
Current Practice:
At least one implementation returns extra values for certain functions
not currently specified to return those values.
Adoption Cost:
Implementations and their associated documentation that now contain
functions that return extra values will have to change.
Benefits:
Programs will potentially become more portable.
Conversion Cost:
See Adoption Cost.
Aesthetics:
None.
Discussion:
∂16-Mar-89 1801 X3J13-mailer SYMBOL-MACROLET-SEMANTICS, version 6
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 18:01:42 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 17:46:06 PST
Date: 16 Mar 89 17:44 PST
From: masinter.pa@Xerox.COM
To: x3j13@sail.stanford.edu
Subject: SYMBOL-MACROLET-SEMANTICS, version 6
line-fold: NO
Message-ID: <890316-174606-6317@Xerox>
This is a proposal to amend version 5, passed in January 1989 in Kauai.
Version 6 amends version 5 to require PSETQ to behave like PSETF,
to require MULTIPLE-VALUE-SETQ to accept symbol macros (but not
general SETF places), and to specify the interaction with the
*MACROEXPAND-HOOK* function.
We would like to have the proposal reconsidered, and
accepted as amended.
!
Issue: SYMBOL-MACROLET-SEMANTICS
References: SYMBOL-MACROLET (88-002R page 2-81)
Related Issues: SYMBOL-MACROLET-DECLARE
Category: CHANGE
Edit history: 29-July-88, Version 1 by Piazza
21-September-88, Version 2 by Piazza
22-September-88, Version 3 by Piazza
22-September-88, Version 4 by Piazza
30-Nov-88, Version 5 by Masinter
14-Mar-89, Version 6 by Steele
Problem Description:
The SYMBOL-MACROLET construct, introduced with CLOS in X3J13 document
88-002R, profoundly alters the interpretation of symbols appearing as
forms in a Common Lisp program--what previously was necessarily a variable
might now be a symbol macro instead. Macros which appear in the body of a
SYMBOL-MACROLET form are currently unable to determine whether a symbol
form is a variable or a symbol macro, and, if the latter, what the
expansion of the symbol macro is. Consequently, complex macros (such as
SETF or PUSH) which depend on the form of their argument(s), are unable to
produce their desired results in some cases, as in the following example:
(let ((a (make-array 5))
(i 0))
(symbol-macrolet ((place (aref a (incf i))))
(push x place))
i) ==> 2
In addition, it would be both natural and nice to be able to write
(with-slots (rho theta) point
(declare (single-float rho theta))
...computation...)
as well as DECLARE within SYMBOL-MACROLET forms.
Proposal (SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM):
Change the definition of SYMBOL-MACROLET to specify that it is a special
form, which affects the evaluation environment for symbols. Enhance
MACROEXPAND and MACROEXPAND-1 so that they can expand a symbol macro.
Modify SETF et al to use the new MACROEXPAND and MACROEXPAND-1 to examine
even symbol subforms. Specify that the expansion of a symbol macro IS
subject to further macro expansion in the same lexical environment as the
symbol macro invocation, exactly analogous to normal macros. Clarify that
within the body of a SYMBOL-MACROLET, SETQ of a symbol defined as
a symbol macro will be treated as if it were a SETF.
Furthermore PSETQ of a symbol defined as a symbol macro will
behave as if it were a PSETF, and MULTIPLE-VALUE-SETQ will behave
as if SETQ were used on each variable to be set.
When MACROEXPAND or MACROEXPAND-1 sees a symbol macro, it calls
the value of *MACROEXPAND-HOOK* in the same manner as for an
ordinary macro. The three values given to the hook function
in this case will be an expansion function, a form (in this case
the symbol naming the symbol macro), and an environment. The
only guaranteed property of the expansion function is that when
it is applied to the form and the environment it will return the
correct expansion of the symbol macro. (In particular, nothing
it said in this specification whether the expansion is conceptually
stored in the expansion function, the environment, or both.)
Rationale:
The potential for interaction between macros is exactly why &environment
arguments were originally added to macros. Changing SYMBOL-MACROLET to be
a special form, which communicates through the &environment arguments to
macros with MACROEXPAND and MACROEXPAND-1, would allow PUSH and SETF
(among others) to work with SYMBOL-MACROLET in the same way they work with
MACROLET.
This change cannot (reasonably) support the currently specified semantics
that the expansion text is "outside" the scope of the symbol macro. For
indeed, when the symbol macro is expanded, (a copy of) the expansion is
then within the scope of the SYMBOL-MACROLET, and should then be subject
to further scrutiny. The issue of "infinite expansion" of symbol macros is
no more dangerous than that of normal macros.
Current Practice:
Portable Common Loops provides a code-walking implementation of
SYMBOL-MACROLET as specified in 88-002R. Symbolics Cloe has both a
code-walking version of a SYMBOL-MACROLET macro and compiler support for
a SYMBOL-MACROLET special form.
Cost to Implementors:
If SYMBOL-MACROLET is modified to be a special form, compilers and
interpreters will have to change, as well as MACROEXPAND, MACROEXPAND-1,
PUSH, INCF, DECF, and others.
Cost to Users:
If SYMBOL-MACROLET is converted to a special form, code-walking programs
will have to be modified to handle SYMBOL-MACROLET correctly. Those same
programs would have to be modified to handle the other special forms
specified in CLOS, anyway.
Cost of Non-Adoption:
SYMBOL-MACROLET will retain its confusing semantics, leading to bugs when
it interacts with complex macros and forms which produce side-effects.
Implementations which support ONCE-ONLY will break. For that matter, any
mechanism which examines code and assumes that "variables" have no side
effects will break.
Benefits:
SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM avoids the hairiest problems
surrounding interaction of macros (like SETF) and side effects, and makes
SYMBOL-MACROLET consistent with MACROLET.
Aesthetics:
If SYMBOL-MACROLET is made to be a special form, aesthetics are improved
by making symbol macros consistent with normal macros.
Discussion:
A case could be made for adding a new function, SYMBOL-MACRO-FUNCTION, as
a dual of MACRO-FUNCTION. However, symbol macros are simpler than normal
macros: a symbol macro is associated with a single expansion form, rather
than an arbitrary function which computes the expansion. For this reason,
the augmented MACROEXPAND-1 proposed here can also fill the role of
SYMBOL-MACRO-FUNCTION: the second value of (macroexpand-1 sym env) will be
T if and only if sym is a symbol macro, while the first value gives the
expansion of sym, if it has one.
Rather than extending the existing MACROEXPAND and MACROEXPAND-1
functions, new functions could be introduced to expand symbol macros.
However, there seems to be no particular reason to do this.
∂16-Mar-89 2103 X3J13-mailer Issue: EXIT-EXTENT, v.6
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 21:03:05 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 21:00:49 PST
Date: 16 Mar 89 20:52 PST
From: masinter.pa@Xerox.COM
Subject: Issue: EXIT-EXTENT, v.6
to: X3J13@sail.stanford.edu
cc: masinter.pa@Xerox.COM
line-fold: NO
Message-ID: <890316-210049-6699@Xerox>
This version was distributed in hardcopy form at the
January 1989 meeting, but was tabled.
There are two proposals.
!
Issue: EXIT-EXTENT
References: CATCH, THROW (p 142),
BLOCK, RETURN, RETURN-FROM,
TAGBODY, GO, UNWIND-PROTECT,
Dynamic extent (CLtL p.37),
Nested dynamic extents (CLtL p.38),
Blocks can only be exited once (CLtL p.120),
Catch is disestablished just before the values
are returned (CLtL p.139).
Related issues: UNWIND-PROTECT-NON-LOCAL-EXIT is superseded
by this one.
Category: CLARIFICATION
Edit history: ... Version 5 of UNWIND-PROTECT-NON-LOCAL-EXIT, 23-May-88 ...
Version 1, 5-Sep-88, by Moon, for discussion
Version 2, 1-Oct-88, by Masinter, minor edits
Version 3, 7-Oct-88, by Moon, wording improvements
Version 4, 7-Dec-88, by Masinter, add MEDIUM from
UNWIND-PROTECT-NON-LOCAL-EXIT, discussion.
Version 5, 12-Dec-88, Masinter, clarify MINIMAL allows MEDIUM
Version 6, 8-Jan-89, Masinter, fix some bugs
Problem description:
CLtL does not specify precisely when the dynamic extent (lifetime)
of a nonlocal exit such as a CATCH, BLOCK, or TAGBODY ends.
For example, at what point is it no longer possible to RETURN-FROM
a particular BLOCK?
An "exit" refers to a point from which control can be transferred.
For a THROW or RETURN-FROM, the "exit" is the corresponding CATCH
or BLOCK body. For a GO, the "exit" is the form within the TAGBODY
which was being executed at the time the GO is performed.
The extent of an exit is dynamic; it is not indefinite. The extent
of an exit begins when the corresponding form (CATCH, BLOCK or TAGBODY
clause) is entered. When the extent of an exit has ended, it is no
longer legal to return from it.
The extent of an exit is not the same thing as the scope of the
designator by which the exit is identified. For example, a BLOCK
name has lexical scope but the extent of its exit is dynamic; the
scope of a CATCH tag could differ from the extent of the CATCH's
return point. (That's part of what is at issue here.)
The ambiguity at issue arises for the case where there are transfers
of control from the cleanup clauses of an UNWIND-PROTECT.
When a transfer of control is initiated by GO, RETURN-FROM or THROW,
a variety of events occur before the transfer of control is complete.
In particular,
(a) the cleanup clauses of any intervening UNWIND-PROTECT clauses
are evaluated,
(b) intervening dynamic bindings of special variables and catch tags
are undone,
(c) intervening exits are "abandoned", i.e., their extent ends and it
is no longer legal to attempt to transfer control through them,
(d) the extent of the exit being invoked ends,
(e) control is finally passed to the target.
The order of these events is not explicit in CLtL, however. The
implementation note on p.142 gives a clue about the interweaving
of (a) and (b), but there are differing opinions about the times
at which (c) and (d) may occur. In particular,
Is it legal for an implementation to end the extent of all
intervening exits before processing the cleanup clauses of intervening
UNWIND-PROTECTs?
What is the dynamic context at the time UNWIND-PROTECT clauses are
evaluated: how is the unwinding of dynamic bindings intertwined with
evaluation of UNWIND-PROTECT cleanup clauses?
Proposal (EXIT-EXTENT:MINIMAL):
The extent of an exit--whether it is being "abandoned" because it is
being passed over, or it is itself the target exit--ends as soon as
the transfer of control is initiated. That is, the events (c) and (d)
at the beginning of the initiation of the transfer of control. In the
language of the implementation note on p.142, the extent ends at the
beginning of the second pass. It is an error to attempt a transfer
of control to an exit whose dynamic extent has ended.
Otherwise, events (a) and (b)--the undoing of dynamic binding of special
variables and CATCH tags, and the execution of UNWIND-PROTECT cleanup
clauses--are performed in the order corresponding to the reverse order
in which they were established, as implied by the implementation note
on p.142. The effect of this is that the cleanup clauses of an UNWIND-PROTECT
will see the same dynamic bindings of variables and CATCH tags as were
visible when the UNWIND-PROTECT was entered.
This proposal is called "minimal" because it gives exits the smallest
extent consistent with CLtL. A program that presumed a longer extent
would be in error. Implementations may support longer extents for
exits than is required by this proposal; in particular, an
implementation which allowed the larger extent of the MEDIUM
proposal below would still conform.
Proposal (EXIT-EXTENT:MEDIUM):
The events of (a), (b), (c) and (d) are interwoven in the reverse
order in which they were established. In particular, the extent of
a passed-over exit ends when control reaches a frame that was
established before the exit was established.
In particular, it is legal, during the evaluation of an UNWIND-PROTECT
cleanup form executed because of a non-local transfer of control, to
initiate a new transfer of control to an exit intervening between the
UNWIND-PROTECT and the original target; the original processing of
transfer of control is abandoned.
Examples:
;; Error under either proposal: BLOCK exits normally before RETURN
(funcall (block nil #'(lambda () (return))))
;; Error under either proposal: normal exit before GO
(let ((a nil))
(tagbody t (setq a #'(lambda () (go t))))
(funcall a))
;; Error under either proposal: TAGBODY is passed over, before GO
(funcall (block nil
(tagbody a (return #'(lambda () (go a))))))
;;returns 2 under MEDIUM, is error under MINIMAL
(block nil
(unwind-protect (return 1)
(return 2)))
;;returns 2 under MEDIUM, is error under MINIMAL
(block a
(block b
(unwind-protect (return-from a 1)
(return-from b 2))))
;; returns 2 under MEDIUM, is error under MINIMAL
(catch nil
(unwind-protect (throw nil 1)
(throw nil 2)))
;; returns 2 under MEDIUM, is error under MINIMAL
;; because the catch of B is passed over by
;; the first THROW, hence portable programs must assume its dynamic extent
;; is terminated. The binding of the catch tag is not yet disestablished
;; and therefore it is the target of the second throw.
(catch 'a
(catch 'b
(unwind-protect (throw 'a 1)
(throw 'b 2))))
;; the following is an error under MINIMAL; the extent of the
;; inner catch terminates as soon as the THROW commences, even
;; though it remains in scope. Thus, the THROW of :SECOND-THROW
;; sees the inner CATCH, but its extent has ended.
;; under MEDIUM, it prints "The inner catch returns :SECOND-THROW"
;; and then returns :OUTER-CATCH.
(catch 'foo
(format t "The inner catch returns ~s.~%"
(catch 'foo
(unwind-protect (throw 'foo :first-throw)
(throw 'foo :second-throw))))
:outer-catch))
;; Following returns 10 under either proposal. The inner
;; CATCH of A is passed over, but because that CATCH
;; is disestablished before the THROW to A is executed,
;; it isn't seen.
(catch 'a
(catch 'b
(unwind-protect (1+ (catch 'a (throw 'b 1)))
(throw 'a 10))))
;; Following is an error under MINIMAL because the extent of
;; the (CATCH 'FOO ...) exit ends when the (THROW 'FOO ...)
;; commences.
;; Under MEDIUM, the pending exit to tag FOO is discarded by the
;; second THROW to BAR and the value 4 is transferred to
;; (CATCH 'BAR ...), which returns 4. The (CATCH 'FOO ...)
;; then returns the 4 because its first argument has returned
;; normally. XXX is not printed.
(CATCH 'FOO
(CATCH 'BAR
(UNWIND-PROTECT (THROW 'FOO 3)
(THROW 'BAR 4)
(PRINT 'XXX))))
;; Following returns 4 under either proposal; XXX is not printed.
;; The (THROW 'FOO ...) has no effect on the scope of the BAR
;; catch tag or the extent of the (CATCH 'BAR ...) exit.
(CATCH 'BAR
(CATCH 'FOO
(UNWIND-PROTECT (THROW 'FOO 3)
(THROW 'BAR 4)
(PRINT 'XXX))))
;;The following are legal and print 5 under either proposal:
(block nil
(let ((x 5))
(declare (special x))
(unwind-protect (return)
(print x))))
(block nil
(let ((x 5))
(declare (special x))
(unwind-protect
(if (test) (return))
(print x))))
Rationale:
For MINIMAL: Giving exits the smallest extent consistent with CLtL
maximizes freedom for implementations; there are few applications,
if any, that require a longer extent.
For MEDIUM: Giving exits a longer extent has cleaner semantics.
Current practice:
Both implementations of Symbolics Genera (3600 and Ivory) end the extent
of a target BLOCK or CATCH at the moment the values are returned, and
end the extent of a passed-over exit at the moment the THROW, RETURN, or
GO commences. This choice of extent maximizes efficiency within the
particular stack structure used by these implementations, by avoiding
the need to retain the control information needed to use a passed over
exit through the transfer of control. Genera signals an error if an
attempt is made to use an exit that has been passed over.
In some implementations, it is possible for a throw or non-local exit
to be effectively "stopped" by an UNWIND-PROTECT cleanup clause that
performs a non-local transfer of control to a passed-over exit.
Some implementations crash or otherwise generate garbage code for
non-local exits from cleanup clauses of UNWIND-PROTECT.
Cost to Implementors:
No currently valid implementation will be made invalid by the MINIMAL
proposal. Some implementors may wish to add error checks if they
do not already have them.
MEDIUM would have a high cost for those implementations that currently
have shorter extent.
Cost to Users:
Most user programs don't do this, so there is likely little cost
of converting existing code in any case. In any case, current implementations
differ enough that this issue ostensibly does not
affect current portable programs. Some users might have code that
relies on the "unstoppable loops" that can be created with the MEDIUM
proposal.
Benefits:
Either proposal would make Common Lisp more precisely defined.
Cost of non-adoption :
The semantics of exits will remain ambiguous.
Esthetics:
Precisely specifying the meaning of dynamic extent improves the language.
Leaving implementations free to implement a longer extent if they choose
can be regarded as unesthetic, but consistent with Common Lisp philosophy.
Having a CATCH that is in scope even though its extent has ended may
seem unesthetic, but it is consistent with how BLOCK behaves.
Discussion:
This issue is controversial. It was first discussed under the issue
named UNWIND-PROTECT-CLEANUP-NON-LOCAL-EXIT. The issue was recast as
the more global one of "extent of exits" rather than the specific
one of "what happens if a cleanup in an UNWIND-PROTECT does a non-
local exit", but the problem cases for both topics are the same.
The goal of the MINIMAL proposal is to clarify the ambiguity in CLtL while
minimizing changes to the current situation. The MEDIUM proposal
defines the extent of an exit to end at the last moment possible
within some particular reference implementation. It has
a cost to implementors whose implementation is not identical to the
reference implementation. Another alternative proposal, not considered
here, would duck the issue by outlawing all non-local exits from UNWIND-PROTECT
cleanup forms. That alternative would have a substantial cost to some users.
Scheme is cleaner: it avoids this issue by specifying that the extent
of an exit never ends.
An argument for the MEDIUM proposal was made based on the example:
(block foo
(block bar
(unwind-protect
(return-from foo 'foo)
(return-from bar 'bar))))
Since there is no reason for FOO and BAR not to be treated interchangeably,
calling this an error would be inappropriate.
It was argued that the MINIMAL proposal is equivalent to practically
outlawing non-local exits from UNWIND-PROTECT cleanup clauses, because
there is no general way to determine the target of the non-local exit
that caused the cleanup clause to be invoked.
The following example was offered as an argument against MINIMAL. Given:
(block nil
(handler-case
(unwind-protect (return)
(error "foo")) ;probably an error, under the proposal
(error ()
(print "foo"))))
If the ERROR handler has the same scope and extent a CATCH in the same place
would have (and that seems reasonable, though I'm not certain that the
condition system specifically requires that interpretation), then the handler
will be apparent to the call to ERROR, but will no longer be a valid target
(its extent was exited by the RETURN in the UNWIND-PROTECT body).
The extent of an object with dynamic extent is the extent of the form
which created it. Code which is executed "within" that form is within
the extent of the object(s). This applies to all dynamic objects, such
as special variable bindings, not just exits. Actually, I think the intent
of the implementation note on p.142 is fairly clear and supports this
interpretation. The supposedly ambiguous use of "frame" should be read
as something like "form which establishes a dynamic extent". It might be
clearer if the last sentence were changed to read something like:
"On the second pass the stack is actually unwound. Each form which establishes
a dynamic extent is undone in reverse order of creation until the matching
CATCH is reached. The meaning of undoing a form depends on the type of form.
For UNWIND-PROTECT, it means executing the cleanup forms. For CATCH it means
removing the CATCH tag. For dynamic bindings it means undoing the binding,
restoring the previous saved value. {This is not an exhaustive listing of the
possibilities.}"
----- End Forwarded Messages -----
∂16-Mar-89 2220 X3J13-mailer Issue: FUNCTION-COERCE-TIME (Version 2)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 22:20:17 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 22:18:04 PST
Date: 16 Mar 89 22:17 PST
Sender: masinter.pa@Xerox.COM
Subject: Issue: FUNCTION-COERCE-TIME (Version 2)
From: cl-cleanup@sail.stanford.edu
To: x3j13@sail.stanford.edu
REPLY-TO: cl-cleanup@sail.stanford.edu
cc: Masinter.pa@Xerox.COM
Message-ID: <890316-221804-6820@Xerox>
Unfortunately, there have been no new versions of this
produced since it was last distributed, labelled DRAFT, to X3J13
prior to the October, 1988 meeting in Fairfax.
Excerpts from the mail on this are appended.
!
Issue: FUNCTION-COERCE-TIME
References: SET-MACRO-CHARACTER (p362),
SET-DISPATCH-MACRO-CHARACTER (p364),
MAP (p249), MAPL (p129), ...
Functions using :TEST, :KEY, etc. (REDUCE, MEMBER, DELETE, ...)
Functions using a positional predicate (SORT, DELETE-IF, ...)
Category: CLARIFICATION
Edit history: 20-Jun-88, Version 1 by Pitman
16-Sep-88, Version 2 by Pitman
(changes to presentation of all proposals per Masinter's comments)
Status: For Internal Discussion
Problem Description:
Many functions which accept arguments which are to be treated functionally
but which are not of type FUNCTION. This functionality can be very useful,
but the time at which the coercion is accomplished must be made clear.
Proposal (FUNCTION-COERCE-TIME:LAZY):
Specify that when a non-function (eg, a symbol) is used as a functional
argument to an operator, the coercion of that non-function to a function
is delayed until the function is about to be called and is done anew
every time the function is to be called. That is, passing a non-function
functional argument, F, is equivalent to passing
#'(LAMBDA (&REST ARGUMENTS)
(APPLY F ARGUMENTS))
Rationale:
One of the main reasons that it may be useful to pass a non-function
instead of a function is to accomplish indirection which allows later
redefinitions to take proper effect. Early binding would tend to
thwart the usefulness of such indirection and force people into
notationally more clumsy devices.
Proposal (FUNCTION-COERCE-TIME:AMBITIOUS):
Specify that when a non-function (eg, a symbol) is used as a functional
argument to an operator, the coercion of that non-function to a function
is done immediately. That is, all such functions treat a non-function
functional argument, F, as if
(COERCE F 'FUNCTION)
had been passed instead.
Rationale:
This is easier to implement since the coercion is done up front and
no further worry about uncoerced functions is needed internally.
Also, inlining of mapped functions (without using temporary storage
to hold a cached value of the function being mapped) can be done
without needing to know whether the function being inlined will
affect the place which holds the functional argument being passed.
Proposal (FUNCTION-COERCE-TIME:HYBRID):
Specify that when a non-function (eg, a symbol) is used as a
functional argument to an operator, the coercion of that non-function
to a function must be done immediately if the functional argument is
to be used only internally to the function (eg, SORT or MAPCAR).
Otherwise, if the functional argument's use persists beyond the end
of the call to the operator (eg, SET-MACRO-CHARACTER), any coercion is
delayed until the function is about to be called and is done anew every
time the function is to be called.
That is, functions like SORT and MAPCAR are permitted to treat a
non-function functional argument, F, as if
(COERCE F 'FUNCTION)
had been passed instead. However, functions like SET-MACRO-CHARACTER
would treat a non-function functional argument, F, as if
#'(LAMBDA (&REST ARGUMENTS)
(APPLY F ARGUMENTS))
were passed instead.
Rationale:
Debugging is enhanced for operations such as SET-MACRO-CHARACTER
without needlessly hampering useful optimizations to things like
SORT or MAPCAR, which very rarely require this facility.
Test Cases:
(DEFVAR *SOME-FUNCTIONS*
(LIST #'(LAMBDA (X) (SETF (SYMBOL-FUNCTION 'FOO) X) 1)
#'(LAMBDA (X) (SETF (SYMBOL-FUNCTION 'FOO) X) 2)
#'(LAMBDA (X) (SETF (SYMBOL-FUNCTION 'FOO) X) 3)
#'(LAMBDA (X) (SETF (SYMBOL-FUNCTION 'FOO) X) 4)))
; Control situation A
(PROGN (SETF (SYMBOL-FUNCTION 'FOO) (CAR *SOME-FUNCTIONS*))
(LIST (MAPCAR #'(LAMBDA (&REST X) (APPLY #'FOO X))
*SOME-FUNCTIONS*)
(FOO T)))
=> ((1 1 2 3) 4)
; Control situation B
(LET ((FOO (SETF (SYMBOL-FUNCTION 'FOO) (CAR *SOME-FUNCTIONS*))))
(LIST (MAPCAR FOO
*SOME-FUNCTIONS*)
(FOO T)))
=> ((1 1 1 1) 4)
; Interesting Situation 1
(PROGN (SETF (SYMBOL-FUNCTION 'FOO) (CAR *SOME-FUNCTIONS*))
(LIST (MAPCAR #'FOO
*SOME-FUNCTIONS*)
(FOO T)))
=> ((1 1 2 3) 4) ;Lazy-1
or ((1 1 1 1) 4) ;Ambitious-1
; Interesting Situation 2
(PROGN (SETF (SYMBOL-FUNCTION 'FOO) (CAR *SOME-FUNCTIONS*))
(LIST (MAPCAR 'FOO
*SOME-FUNCTIONS*)
(FOO T)))
=> ((1 1 2 3) 4) ;Lazy-2
or ((1 1 1 1) 4) ;Ambitious-2
(DEFUN SHARP-DOLLAR (STREAM CHAR N)
(DECLARE (IGNORE CHAR))
(EXPT (READ STREAM) (OR N 1)))
(SET-DISPATCH-MACRO-CHARACTER #\# #\$ 'SHARP-DOLLAR)
(VALUES (READ-FROM-STRING "(#$3 #4$3)"))
=> (3 81)
(DEFUN SHARP-DOLLAR (STREAM CHAR N)
(DECLARE (IGNORE CHAR))
(+ (READ STREAM) (* (OR N 0) 0.01)))
(VALUES (READ-FROM-STRING "(#$3 #4$3)"))
=> (3.0 3.04) ;Lazy-3
(3 81) ;Ambitious-3
Proposal LAZY requires LAZY-1, LAZY-2, LAZY-3.
Proposal AMBITIOUS requires AMBITIOUS-1, AMBITIOUS-2, AMBITIOUS-3.
Proposal HYBRID requires AMBITIOUS-1, AMBITIOUS-2, LAZY-3.
Current Practice:
Implementations are permitted to differ in when they do the coercion since
the coercion time is not clearly spelled out.
(In the test case, LAZY-1 can occur only if MAPCAR is inlined, and then
only if the original value of the function definition is not cached.)
[Some info below is based on empirical testing -- I didn't look at the
source or try to see how speed/safety affect things. -kmp]
Symbolics Genera implements AMBITIOUS-1 interpreted and LAZY-1 compiled.
Symbolics Cloe (a compiled-only lisp) implements LAZY-1 both `interpreted'
and compiled.
Both Symbolics Genera and Symbolics Cloe implement LAZY-2.
Symbolics Genera implements LAZY-3.
Symbolics Cloe implements AMBITIOUS-3.
Cost to Implementors:
[Costs may vary widely depending on current practice.
I'll leave this one open for now pending feedback from others. -kmp]
Cost to Users:
This change is upward compatible.
Cost of Non-Adoption:
A very important aspect of the language would be left unspecified.
Portability would suffer.
Benefits:
HYBRID has the benefit of making things like readmacros easier to debug.
LAZY offers the additional benefit of being able to repair certain
functional arguments to SORT or MAPCAR (eg, as a symbol) in the debugger,
and then to proceed the error (in implementations offering that restart
option) in a way that makes the ongoing call to SORT or MAPCAR notice
the repairwork right away.
Aesthetics:
Since this is a visible aspect of the language, anything which clarified
the behavior that a programmer might expect would seem to improve the
aesthetics somewhat.
Discussion:
This issue was raised by Nick Gall and written up by Pitman.
Pitman supports FUNCTION-COERCE-TIME:HYBRID.
!
Additional comments:
There was some concern about the proposal wording, because
it was trying to allow for the possibility that implementations
might extend other objects (e.g., lists that begin with
LAMBDA) to "coerce" to functions, and the proposal should
apply for them, too.
This made the wording of the proposal pretty awkward, though.
- - - - - -
The writeup for the LAZY option should mention that this might cause a
substantial performance hit in some implementations.
Of the options presented, I prefer AMBITIOUS. However, I would really
much rather see this whole issue left explicitly vague in the
standard.
- - - -
notes from Cleanup meeting (Fairfax, 1988):
Eliminate the AMBITIOUS proposal. Continue to evolve the
HYBRID and LAZY variants.
Relation to DEBUG quality.
There was some discussion about the idea of permitting vagueness
(ie, making LAZY/AMBITIOUS optional in some places).
X3J13 meeting:
Some people weren't completely convinced that the HYBRID proposal
would feel predictable enough. Others disagreed.
- - - - - - - -
Well, the main reason why I prefer "AMBITIOUS" to "HYBRID" is that it
seems kind of peculiar to make an exception for the two functions,
SET-MACRO-CHARACTER and SET-DISPATCH-MACRO-CHARACTER. Besides being
different from all the other functions that take functional arguments,
it makes them different from the pathname functions (which always
coerce non-pathname "pathname" arguments to pathnames) and the package
functions (which always coerce non-package "package" arguments to
packages).
Also, I disagree that there is no performance penalty, although it's
certainly small in comparison to the rest of the reader's processing.
For example, A-Lisp has a fast, opencoded funcall primitive that it
uses when its argument is guaranteed to be a function, which is *much*
faster than a normal funcall (by a factor of at least 20).
I don't feel really strongly about this -- HYBRID is not really all
that objectionable to me, and I would vote for it if AMBITIOUS is
thrown out.
-------
... I'm thinking of a revision which might lean more toward
explicitly vague on some of these issues. At the same time,
I'd like to encourage the use of the DEBUG and/or SPEED quality
to help compilers lean toward LAZY in the slow/easy-to-debug
case and AMBITIOUS in the fast/hard-to-debug case. There are
some details to be worked out, though...
∂16-Mar-89 2254 X3J13-mailer Issue: HASH-TABLE-ACCESS (version 2)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 22:53:48 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 22:51:36 PST
Date: 16 Mar 89 22:51 PST
From: masinter.pa@Xerox.COM
Subject: Issue: HASH-TABLE-ACCESS (version 2)
to: X3J13@sail.stanford.edu
Line-fold: NO
Message-ID: <890316-225136-6875@Xerox>
Version 1 of this issue was distributed prior
to the October 1988 meeting.
This version was produced in response to
comments there.
Additional comments are at the end.
!
Issue: HASH-TABLE-ACCESS
References: hash-tables (Chapter 21 of CLtL)
Category: ADDITION
Edit History: 13-Sept-88, version 1 by Walter van Roggen
13-Oct-88, version 2 by Walter van Roggen
Problem Description:
There are many characteristics of hash-tables which are specified upon
creation but are not accessible afterwards.
Proposal: (HASH-TABLE-ACCESS:PROVIDE)
Add the following functions to the language:
HASH-TABLE-REHASH-SIZE hash-table
Returns the current rehash size of a hash table.
HASH-TABLE-REHASH-THRESHOLD hash-table
Returns the current rehash threshold of a hash table.
HASH-TABLE-SIZE hash-table
Returns the current size of a hash table.
HASH-TABLE-TEST hash-table
Returns the test used for comparing keys in the hash table.
By default the value will be EQL.
Current Practice:
VAX LISP and Lucid 3.0 implement the proposal.
Cost to Implementors:
Most of these should be trivial to implement, since the information
must be present for nearly all types.
Cost to Users:
None. This is an upward-compatible extension.
Cost of Non-Adoption:
The benefits would not be available in a portable fashion.
Benefits:
Programs would be able to access useful information otherwise hidden.
For example, it would allow programs to gain statistics about hash
table usage that might enable better tuning.
Discussion:
None of these are required to be SETF'able, though some might be
reasonable implementation-dependent extensions. Including such
modification abilities might constrain some implementations unduly.
This first appeared in ">GLS>clarifications.text" of 12/06/85.
!
Additional Comments:
Adding accessors for hash tables seems like a reasonable idea to me,
but I don't like the idea of being able to SETF them.
- - - - -
HASH-TABLE-REHASH-SIZE hash-table
Returns the current rehash size of a hash table.
HASH-TABLE-REHASH-THRESHOLD hash-table
Returns the current rehash threshold of a hash table.
HASH-TABLE-SIZE hash-table
Returns the current size of a hash table.
I don't think the "current" values of these are well defined except in
reference to one particular implementation technique (I believe the
corresponding arguments to make-hash-table are advisory in nature and can be
ignored when not applicable). For instance, can you describe what an
implementation using alists should return from each of these functions?
I do support the addition of HASH-TABLE-TEST.
- - - - - - -
Well, I think there would be some leeway on the return values for
HASH-TABLE-REHASH-SIZE/REHASH-THRESHOLD/SIZE too.
If an implementation really did implement them with association lists,
perhaps reasonable return values would be:
HASH-TABLE-REHASH-SIZE 1
HASH-TABLE-REHASH-THRESHOLD 1.0
HASH-TABLE-SIZE the length of the association list
- - - - - - -
I still would like to see SETF enabled for:
HASH-TABLE-REHASH-SIZE
HASH-TABLE-REHASH-THRESHOLD
At issue is the rate of "rehashing" between successive, novel entries
into the table, and the rate of consing to maintain the table. [Perhaps
this would be clearer if there were a function in the language called
REHASH; Lucid 3.0 has such a function, and Interlisp-D had such a function.]
Of course, the setf methods for these two accessors would do a good deal of
argument and consistency checking. So what possible harm could come from
permitting the user to alter these parameters after initial creation? those
implementations that substitute alists for "hash-tables" can try to adapt to
this view, that some kind of "rehash" step [with some determined cost] is
done after the entry which first makes:
(hash-table-count x) > (* (hash-table-size x)
(hash-table-rehash-threshold x))
be true [assuming a floating-point value for the threshold]. This is part
of the whole point for having "hash tables" in the language.
- - - - -
I'm quite sympathetic to being able to SETF some of the hash-table readers,
but I didn't think it appropriate to require of all implementations.
- - - - - -
The value of HASH-TAbLE-REHASH-SIZE and HASH-TAbLE-REHASH-THRESHOLD are
implementation dependent, and guaranteed to be greater than or equal to the
values given to MAKE-HASH-TABLE, and idempotent, in that if you make a hash
table with the same values as a given hash table then the -REHASH-SIZE and
-REHASH-THRESHOLD of the newly created one will be the same as the input
values. (This says that they may be thresholded upward in some
implementation-dependent-manner.)
HASH-TABLE-SIZE should be greater than or equal to the count of things
MAPHASH would iterate over, and HASH-TABLE-TEST will return one of the
symbols EQ EQL EQUAL (or, if HASH-TABLE-TESTS passes, EQUALP), even if #'EQ
#'EQUAL #'EQL are given.
Normally implementation-dependent-extensions are explicitly discouraged;
I'm no longer sure at the momemnt whether PACKAGE-CLUTTER would explicilty
disallow such extensions unless they are explicitly allowed, but we should
be cautious in throwing around phrases like "might be
reasonable implementation-dependent extensions" if we don't mean it. I
would take that out, actually.
∂16-Mar-89 2244 X3J13-mailer Issue: SETF-FUNCTION-VS-MACRO, SETF-PLACES, FUNCTION-NAME, v.1
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 22:43:21 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 22:40:08 PST
Date: 16 Mar 89 22:34 PST
From: masinter.pa@Xerox.COM
Subject: Issue: SETF-FUNCTION-VS-MACRO, SETF-PLACES, FUNCTION-NAME, v.1
To: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-224008-6866@Xerox>
This issue has been renamed several times; however, it is
the same old issue. I say this lest anyone think we can
'two week' it away.
We didn't have a 'letter ballot' and so we have to talk
about it. Maybe.
Additional Comments are at the end; including a fairly substantial
additional proposal.
!
Issue: FUNCTION-NAME
References: SETF rules for what -place- can be (pp.94-7)
FBOUNDP function (p.90)
FMAKUNBOUND function (p.92)
FUNCTION special form (p.87)
SYMBOL-FUNCTION and setf of symbol-function (p.90)
88-002R pages 1-21, 2-21, 2-26, 2-39, 2-44, 2-46, 2-51, and 2-55
(There are additional references for the MEDIUM and LARGE
proposals, but they are not listed here. They're obvious.)
Related issues: SETF-FUNCTION-VS-MACRO, SETF-PLACES (both subsumed by this)
Category: ADDITION
Edit history: Version 1, 23-Jan-89, by Moon
(based on discussion at X3J13 meeting)
Problem description:
The Common Lisp Object System needs a well-defined way to relate the name
and arguments of a writer function to those of a reader function, because
both functions can be generic and can have user-defined methods. The way
that was adopted into Common Lisp when X3J13 voted to accept document
88-002R was to use a list (SETF reader) as the name of the writer function.
Some changes to the non-object-oriented portion of Common Lisp are required
in order to support this.
This issue has three proposals.
Proposal (FUNCTION-NAME:SMALL):
Add a new concept "function-name" (called "function-specifier" in
88-002R). A function-name is either a symbol or a 2-element list whose
first element is the symbol SETF and whose second element is a symbol.
Implementations are free to extend the syntax of function-names to
include lists beginning with additional symbols other than SETF.
Add a new function (FDEFINITION function-name), which returns the
current global function definition named by function-name, or signals
an error if there is no global function definition. This follows all
the same rules listed for SYMBOL-FUNCTION in CLtL p.90.
Add SETF of FDEFINITION to change the current global function definition
named by a function-name. This follows all the same rules listed for
SETF of SYMBOL-FUNCTION in CLtL p.90.
Change the FBOUNDP and FMAKUNBOUND functions, and the FUNCTION special
form, to accept function-names in place of symbols. Implementation
defined extensions to the syntax of function-names cannot use the
symbol LAMBDA, since FUNCTION already uses that symbol.
Change the rules for SETF places (CLtL pp.94-7) by adding the following
clause after all the existing clauses:
- Any other list whose first element is a symbol, call it reader.
In this case, SETF expands into a call to the function named by the
list (SETF reader). The first argument is the new value and the
remaining arguments are the values of the remaining elements of
-place-. This expansion occurs regardless of whether reader or
(SETF reader) is defined as a function locally, globally, or not at
all. For example,
(SETF (reader arg1 arg2...) new-value)
expands into a form with the same effect and value as
(LET ((#:temp-1 arg1) ;force correct order of evaluation
(#:temp-2 arg2)
...
(#:temp-0 new-value))
(FUNCALL (FUNCTION (SETF reader)) #:temp-0 #:temp-1 #:temp-2...)).
Change the functions GET-SETF-METHOD and GET-SETF-METHOD-MULTIPLE-VALUE
to implement the above change to the rules.
Document that a function named (SETF reader) should return its first
argument as its only value, in order to preserve the semantics of SETF.
Change the macro DEFGENERIC and the function ENSURE-GENERIC-FUNCTION to
refer to the function FDEFINITION where they now refer to the function
SYMBOL-FUNCTION.
Change the macros DEFCLASS, DEFGENERIC, and DEFMETHOD, the special forms
GENERIC-FLET and GENERIC-LABELS, and the functions DOCUMENTATION and
ENSURE-GENERIC-FUNCTION to use the term "function-name" where they now
use the term "function-specifier" or "function specifier".
Rationale for FUNCTION-NAME:SMALL:
This is the minimum change to Common Lisp needed to do what 88-002R says
about (SETF reader). Giving implementations freedom to extend the syntax
of function-names allows for current practice. Changing the name from
"function-specifier" to "function-name" avoids confusion and improves
consistency with the rest of the language, at the cost of a few small
changes to 88-002R.
Proposal (FUNCTION-NAME:MEDIUM):
Everything in FUNCTION-NAME:SMALL, and in addition:
Change the DEFUN macro to accept a function-name for its name argument,
instead of only accepting a symbol. If function-name is (SETF sym),
the body is surrounded by an implicit block named sym.
Rationale for FUNCTION-NAME:MEDIUM:
Keeping DEFUN consistent with DEFMETHOD is a good idea. Also 88-002R
says "The name of a generic function, like the name of an ordinary
function, can be either a symbol or a two-element list whose...", which
implies this change to DEFUN.
Proposal (FUNCTION-NAME:LARGE):
Everything in FUNCTION-NAME:MEDIUM, and in addition the following
numbered points, each of which could be adopted independently,
except where explicitly noted:
1. Change the function COMPILE to accept a function-name as its name
argument.
2. Change the function DISASSEMBLE to accept a function-name as its name
argument.
3. Change the FTYPE, INLINE, and NOTINLINE declarations and proclamations
to accept function-names, not just symbols, as function names.
4. Change the FLET and LABELS special forms to accept a function-name in
the name position, not just a symbol.
5. Change the TRACE and UNTRACE macros to accept function-names, not just
symbols, in the function name positions.
6. Change the ED function to accept (ED function-name) in place of
(ED symbol).
7. Change the syntax of a function call to allow a function-name as the
first element of the list, rather than allowing only a symbol.
8. Change the DEFMACRO macro and the MACROLET special form to accept a
function-name in the name position, not just a symbol. Change the
MACRO-FUNCTION function to accept function-names, not just symbols.
Change the last rule for SETF places to use
((SETF reader) #:temp-0 #:temp-1 #:temp-2...)
in place of
(FUNCALL (FUNCTION (SETF reader)) #:temp-0 #:temp-1 #:temp-2...)
so that (SETF reader) can be defined as a macro. This depends on item
7. If item 4 is rejected, MACROLET should be stricken from this item.
9. Add an optional environment argument to FDEFINITION, SETF of
FDEFINITION, FBOUNDP, and FMAKUNBOUND. This is the same as the
&environment argument to a macroexpander. This argument can be used to
access local function definitions, to access function definitions in the
compile-time remote environment, and to modify function definitions in
the compile-time remote environment.
10. Change the second, third, fourth, fifth, seventh, and ninth rules for
SETF places so that they only apply when the function-name refers to the
global function definition, rather than a locally defined function or
macro. (The ninth rule is the one that refers to DEFSETF and
DEFINE-SETF-METHOD; the other rules listed are the ones that list
specific built-in functions). The effect of this change is that SETF
methods defined for global functions are ignored when there is a local
function binding; instead, the function named (SETF reader), which may
have a local function binding, is called. This change is most useful
in connection with item 4, but does not actually depend on it.
11. Clarify that the eighth rule for SETF places (the one for macros)
uses MACROEXPAND-1, not MACROEXPAND.
Rationale for FUNCTION-NAME:LARGE:
This extends the new feature throughout the language, in order to make
things generally more consistent and powerful. Point by point:
1,2,3 - one should be able to compile, examine, and make declarations
about functions regardless of whether they are named with symbols or
with lists.
4 - locally defined non-generic SETF functions are a logical companion
to locally defined generic SETF functions, which can be defined with
GENERIC-FLET or GENERIC-LABELS. They make sense on their own, since one
might define a local reader function and want a local writer function
to go with it.
5,6 - one should be able to apply development tools to functions
regardless of how they are named. The function DOCUMENTATION was already
updated to work for function-names by 88-002R. There might be some
difficulty with implementation-dependent syntax extensions to TRACE and
UNTRACE conflicting with this new syntax.
7 - this restores consistency between the FUNCTION special form and the
first element of a function call form.
8 - it seems more consistent to allow macros to be named the same way
that ordinary functions are named. However, this might be considered
redundant with DEFSETF.
9 - this is not needed by the "chapter 1 and 2" level of CLOS, but might
be used by the metaobject based implementation of ENSURE-GENERIC-FUNCTION.
10 - this change was in SETF-FUNCTION-VS-MACRO and makes item 4 more useful.
11 - this change was in SETF-FUNCTION-VS-MACRO and is a good idea, but
actually is independent of everything else being proposed here.
Examples:
;This is an example of the sort of syntax 88-002R allows
(defmethod (setf child) (new-value (parent some-class))
(setf (slot-value 'child parent) new-value)
(update-dependencies parent)
new-value)
(setf (child foo) bar)
;If SETF of SUBSEQ was not already built into Common Lisp,
;it could have been defined like this, if the MEDIUM or LARGE
;proposal is adopted.
(defun (setf subseq) (new-value sequence start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
;The preceding example would have to be defined like this
;if only the SMALL proposal is adopted. This is a method
;all of whose parameter specializer names are T.
(defmethod (setf subseq) (new-value sequence start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
;Another example, showing a locally defined setf function
(defun frobulate (mumble)
(let ((table (mumble-table mumble)))
(flet ((foo (x)
(gethash x table))
((setf foo) (new x)
(setf (gethash x table) new)))
..
(foo a)
..
(setf (foo a) b))))
;get-setf-method could implement setf functions by calling
;this function when the earlier rules do not apply
(defun get-setf-method-for-setf-function (form)
(let ((new-value (gensym))
(temp-vars (do ((a (cdr form) (cdr a))
(v nil (cons (gensym) v)))
((null a) v))))
(values temp-vars
(cdr form)
(list new-value)
`(funcall #'(setf ,(car form)) ,new-value ,@temp-vars)
`(,(car form) ,@temp-vars))))
Current practice:
No implementation supports exactly what is proposed. Symbolics Genera
and the TI Explorer support something close to the MEDIUM proposal, but
differing in a number of details. Symbolics Genera supports items 1, 2,
3, 6, and 11, and modified forms of items 5 and 8, of the LARGE proposal.
Moon considers this proposal's variations from Symbolics current practice
to be an improvement, although incompatible in some cases.
Many implementations currently support only symbols as function names.
Symbolics Genera and the TI Explorer have some additional function-name
syntaxes.
Cost to Implementors:
The SMALL and MEDIUM proposals are estimated to be no more than 50 lines
of code and require no changes to the "guts" of the interpreter and
compiler. Most of the code for this can be written portably and was
shown on two slides at the X3J13 meeting.
Some of the changes in the LARGE proposal are trivial, some require
the compiler to use EQUAL instead of EQ to compare function names, and
items 4, 7, and 8 might require a more substantial implementation
effort. Even that effort is estimated to be negligible compared to
the effort required to implement CLOS.
Cost to Users:
No cost to users, other than program-understanding programs, since this
is an upward compatible addition.
As with any language extension, some program-understanding programs may
need to be enhanced. A particular issue here is programs that assume
that all function names are symbols. They may use GET to access
properties of a function name or use EQ or EQL (perhaps via MEMBER or
ASSOC) to compare function names for equality. Such programs will need
improvement before they can understand programs that use the new feature,
but otherwise they will still work.
Cost of non-adoption:
We would have to make some other language change since the language
became inconsistent when 88-002R was adopted.
Performance impact:
This has no effect on performance of compiled code. It might slow
down the compiler and interpreter but not by very much.
Benefits:
CLOS will work as designed.
Esthetics:
Some people dislike using anything but symbols to name functions.
Other people would prefer that if the change is to be made at all,
the LARGE proposal be adopted so that the language is uniform in its
treatment of the new extended function names. Other proposals for
how to deal with SETF in CLOS were considerably less esthetic,
especially when package problems are taken into account.
SETF would be more esthetic, but less powerful, if it had only the
proposed setf functions and did not have setf macros. Such a major
incompatible change is of course out of the question; however, if setf
functions are stressed over setf macros, SETF will be much easier to
teach.
Discussion:
Moon supports at least FUNCTION-NAME:MEDIUM. He does not necessarily
approve of all parts of FUNCTION-NAME:LARGE.
!
Additional Comments:
On the whole, I like this presentation much better than either of the
other two writeups that were circulated previously. I suspect that it
might be necessary to vote on each of the items in the LARGE proposal
individually, though. I think I would support items 1, 2, and 11, and
don't have any particular objections to 3, 5, and 6. For item 4, if
consistency with GENERIC-FLET and GENERIC-LABELS is an object, another
alternative is to change those two special forms to be like ordinary
FLET and LABELS, instead of vice versa.
- - - - - - -
I support FUNCTION-NAME:MEDIUM and may support LARGE once I think about
it some more.
As I explained in Hawaii, support for either of these is based on the
:conc-name bugs being removed from the condition system. Of course, I
believe the best way to do that is to CLOSify it.
- - - - - - - -
I'm still thinking about this, but while I am I wanted point out that
MEDIUM is unacceptable to me because I don't think FLET and DEFUN should
disagree on what they permit as defined names. If FLET were added to
MEDIUM, I suspect I'd think it was an internally consistent position.
LARGE has an appeal to me in general, but I'm still mulling over
the specifics.
- - - - - - - - - -
I favor the FUNCTION-NAME:LARGE proposal, because it defines a single,
useful notion of what a function name is. The other proposals have
the flaw that there are two kinds of function names: symbols, and
extended names, with only some of the Lisp primitives accepting the
latter. This may be convenient for some implementations, for the
short term, but it fragments the language.
I have two other comments on the proposal.
A. Reducing the Cost to Implementors
One observation you could put in the Cost To Implementors section is
that none of the SMALL, MEDIUM, or LARGE proposals require changes to
the "guts" of the interpreter and compiler. This is because an
implementation is free to use plain symbols internally to name
functions, and use a hack like JonL's SETF:|3.FOO.BAR| mapping to
convert non-symbol names to symbols. This conversion would be done as a
part of parsing the handful of forms which accept function names, and
then all other passes of the interpreter and compiler (the "guts") would
just see symbols. (By "parsing" I mean ensuring the right number and
type of syntactic subforms. You can see that this is a very early and
simple stage of processing.) Or, Lisp compilers with an "alphatization"
phase could perform function name symbolization at that phase.
B. Finishing the Job of Regularization
I'd like to suggest two additions to your smorgasbord of options in the
FUNCTION-NAME:LARGE section of the proposal. One addition would
regularize a major special case of functions--lambda expressions. The
other addition would reaffirm an unstated regularity in the language,
that function names can stand in for functions under FUNCALL and APPLY.
Not only can the treatment of symbolic and setf-list function names be
regularized, but lambda too can be treated in a consistent manner.
If these two points are added to your proposal, the language as a whole
would have a completely uniform treatment of functions and function
names. Here they are:
13. Declare that any function name is a suitable argument to FUNCALL and
APPLY. In such a case, the function name is passed to FDEFINITION,
and the result (which may in turn be a function name) is called.
That is, the following two expressions are equivalent, when fname
is a function name:
(FUNCALL fname x y)
<==>
(FUNCALL (FDEFINITION fname) x y)
Note that the definition is sought in the global environment.
Compare with the rule which applies to a function name occurs,
syntactically, as the car of a list in code:
(fname x y)
<==>
(FUNCALL (FUNCTION fname) x y)
<==> (under proposal item 9)
(FUNCALL (FDEFINITION fname <local-environment>) x y)
12. Declare that any lamba expression (i.e., a list whose car is LAMBDA and
whose cdr is a well-formed lambda argument list and body) is a function
name. The effects of the function name accessors on lambda expressions
are as follows. FDEFINITION returns an implementation-defined value which
is the function specified the lambda expression, closed in the global
environment. This FDEFINITION value cannot be changed by SETF.
FBOUNDP always returns T, and MAKUNBOUND is an error.
Esthetics:
The effect of items 11 and 12 is to complete the regularization of
Common Lisp's treatment of functions and function names. The total
effect of proposal items 1 through 12 is that Lisp has just two notions
for referencing function objects: FUNCTIONS, which are Lisp objects that
directly represent executable code, and FUNCTION NAMES, which can denote
functions. Symbols, SETF function names, and lambda expressions are all
examples of the latter notion. The former notion is highly
implementation dependent. Function names can occur as syntactic
entities in code. FUNCALL and APPLY work uniformly on both functions
and function names, with a consistent semantics.
Lambda expressions are often thought to denote "anonymous" functions, so
it may seem paradoxical to treat them as names. The paradox is only
apparent, since the expression itself has the properties of a Lisp
function name: It is (typically) a cons tree which can be read, printed,
and stored in source files, and it denotes a well-defined Lisp function.
Benefit to Users:
Function names are useful for representing objects in remote
environments, because they need not be bound at all times to the same
function, or to any function, and because they are typically stable in
meaning across reads and prints, where plain functions are not.
Programs which deal simultaneously with remote and local environments,
such as CLOS, can probably be simplified, since function names
can be used uniformly, rather than an ad-hoc mixture of functions
and function names.
The language as a whole become more uniform from these additions and
clarifications, making it easier to learn and use. (See Esthetics.)
Cost to Implementors:
Interpreters which currently have a special case check for application
of lambda expressions would need to modify this check to call
FDEFINITION when a list of any sort is encountered. Note that all
Common Lisps already must perform some such check, since lambda
expressions can be funcalled (and this is currently a very special case,
the only standard case of a list being funcalled). This means that
every Lisp already has a place to insert the required call to
FDEFINITION.
In some implementations, FDEFINITION of a lambda expression could be that
lambda-expression itself. In others featuring a pre-eval codewalk, the
walk would be done by FDEFINITION, which would return an appropriate
closure.
Cost of Non-adoption:
Rather than two notions for function references (functions and function
names), there would be several notions, each corresponding to the valid
inputs for particular group of primitives. APPLY and FUNCALL would
accept functions, symbolic names, and lambda expressions, but not setf
function names. FDEFINITION and its kind would accept symbols and setf
function names but not lambda expressions. If the :LARGE proposal is
not adopted, this fragmentation would also apply to the various syntaxes
involving function names; some names would be acceptable to DEFUN
but not to FLET, etc.
- - - - - - - - - - - - -
> 13. Declare that any function name is a suitable argument to FUNCALL and
> APPLY. In such a case, the function name is passed to FDEFINITION,
> and the result (which may in turn be a function name) is called.
I don't think this is such a good idea. The case of automatically coercing
a symbol to a function is needed because it provides a portable mechanism
for indirect addressing of a function; I haven't seen a reason to need this
for non-symbol function specs. But more important is that coercing a
symbol to a function is a trivial operation that is reasonable to do at
run time on each call without adding a significant amount of overhead.
FDEFINITION, on the other hand, is a much more expensive operation -- at
best it might use GET to do a property list lookup, or it could be using
string-append and INTERN to convert the name to a symbol. In either case,
I think this is more work than you want to do on each call.
> 12. Declare that any lamba expression (i.e., a list whose car is LAMBDA and
> whose cdr is a well-formed lambda argument list and body) is a function
> name. The effects of the function name accessors on lambda expressions
> are as follows. FDEFINITION returns an implementation-defined value which
> is the function specified the lambda expression, closed in the global
> environment. This FDEFINITION value cannot be changed by SETF.
> FBOUNDP always returns T, and MAKUNBOUND is an error.
The exceptions for SETF and MAKUNBOUND show that this is not really as
consistent as you might like. Furthermore, the FUNCTION special form would
have to treat a LAMBDA expression as a function, not a function name, in
order for it to be lexically scoped. It seems like this might just cause
confusion rather than consistency.
∂16-Mar-89 2334 X3J13-mailer Issue LOOP-AND-DISCREPANCY, version 1
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 23:34:11 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 23:32:03 PST
Date: 16 Mar 89 23:31 PST
From: masinter.pa@Xerox.COM
To: X3J13@sail.stanford.edu
Subject: Issue LOOP-AND-DISCREPANCY, version 1
line-fold: NO
Message-ID: <890316-233203-6953@Xerox>
!
Issue: LOOP-AND-DISCREPANCY
References: Loop Facility document X3J13/89-004
Related issues:
Category: CHANGE CLARIFICATION
Edit history: Version 1, 15-Mar-88 by Steele
Problem description:
The treatment of the AND conjunction in FOR/AS and WITH clauses is not
consistent. Examples of the use of WITH are also not consistent in this
respect.
Page 2-5 implies by example that when AND is used to join two
FOR/AS clauses, the word FOR or AS must occur after the word AND.
Page 2-31 has formal syntax specifying that when AND is used to join two
WITH clauses, the word WITH must *not* occur after the word AND. Examples
on that page are consistent with this specification.
Page 2-41 has an example in which WITH is repeated after AND.
Proposal (LOOP-AND-DISCREPANCY:NO-REITERATION):
Let stand the formal syntax for WITH.
Change the description of FOR/AS clauses to specify that when
two or more such clauses are joined with AND, clauses after the
first do not have FOR or AS before them.
The complete formal syntax for FOR/AS may be described as follows:
for-as ::= {FOR | AS} for-as-subclause {AND for-as-subclause}*
for-as-subclause ::= for-as-arithmetic | for-as-in-list
| for-as-on-list | for-as-equals-then
| for-as-across | for-as-hash | for-as-package
for-as-arithmetic ::= var [type-spec] ...
and so on.
Examples:
> (loop for x from 1 to 10 ;Corrected from X3J13/89-004, page 2-5
and y = nil then x
collect (list x y))
((1 NIL) (2 1) (3 2) (4 3) (5 4) (6 5) (7 6) (8 7) (9 8) (10 9))
> (loop with (a b) float = '(1.0 2.0) ;Corrected from X3J13/89-004, page 2-41
and (c d) integer = '(3 4)
and (e f)
return (list a b c d e f))
(1.0 2.0 3 4 nil nil)
Rationale:
The treatment of AND should be internally consistent. There is no reason
to repeat the FOR/AS keyword. Not repeating the keyword emphasizes that
the subclauses are functionally linked under the heading of WITH or FOR.
(Compare to the third use of AND in LOOP, to link clauses controlled
by WHEN/IF/UNLESS. One does not repeat the WHEN; rather, the clauses
grouped by AND are controlled by a single WHEN.)
Current practice:
Symbolics LOOP allows FOR to be included or omitted after AND,
with identical meanings. WITH may not be repeated after AND.
Cost to Implementors: Small?
Cost to Users: Possible incompatibility with existing implementors' extensions.
Cost of non-adoption: Utter confusion.
Performance impact: None.
Benefits: Consistent treatment of AND within LOOP.
Esthetics:
Absolutely none. We're talking about LOOP here.
Discussion:
Steele supports this proposal. It is a reversal of his previous
suggestion on the topic, thanks to feedback from Moon.
----- End Forwarded Messages -----
∂16-Mar-89 2330 X3J13-mailer Issue: LOAD-OBJECTS (Version 3)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89 23:30:04 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 23:27:37 PST
Date: 16 Mar 89 23:26 PST
From: masinter.pa@Xerox.COM
Subject: Issue: LOAD-OBJECTS (Version 3)
To: x3j13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-232737-6946@Xerox>
Version 1 was distributed in hardcopy form and discussed
at the January 1989 meeting.
Discussion so far has been considering alternatives of
load functions rather than load forms, or having two
generic functions.
!
Issue: LOAD-OBJECTS
References: none
Related issues: LOAD-TIME-EVAL,
CONSTANT-COMPILABLE-TYPES,
CONSTANT-CIRCULAR-COMPILATION
Category: ADDITION
Forum: Cleanup
Edit history: Version 1, 2-Jan-89, by Moon (for discussion)
Version 2, 13-Jan-89, by Moon (draft updated from discussion)
Version 3, 9-Mar-89, by Moon (changes suggested by discussion)
Problem description:
Common Lisp doesn't provide any way to use an object of a user-defined
type (defined with DEFCLASS or DEFSTRUCT) as a constant in a program
compiled with COMPILE-FILE. The problem is that LOAD has to be able
to "reconstruct" an equivalent object when the compiled-code file is
loaded, but the programmer has no way to tell LOAD how to do that.
Proposal (LOAD-OBJECTS:MAKE-LOAD-FORM):
Define a new generic function named MAKE-LOAD-FORM, which takes one
argument and returns two values. The argument is an object that is
referenced as a constant or as a self-evaluating form in a file being
compiled by COMPILE-FILE. The objective is to enable LOAD to
construct an equivalent object.
The first value, called the "creation form," is a form that, when
evaluated at load time, should return an object that is equivalent to
the argument. The exact meaning of "equivalent" depends on the type
of object and is up to the programmer who defines a method for
MAKE-LOAD-FORM. This is the same type of equivalence discussed
in issue CONSTANT-COMPILABLE-TYPES.
The second value, called the "initialization form," is a form that,
when evaluated at load time, should perform further initialization of
the object. The value returned by the initialization form is ignored.
If the MAKE-LOAD-FORM method returns only one value, the
initialization form is NIL, which has no effect. If the object used
as the argument to MAKE-LOAD-FORM appears as a constant in the
initialization form, at load time it will be replaced by the
equivalent object constructed by the creation form; this is how the
further initialization gains access to the object.
Both the creation form and the initialization form can contain
references to objects of user-defined types (defined precisely below).
However, there must not be any circular dependencies in creation forms.
An example of a circular dependency is when the creation form for the
object X contains a reference to the object Y, and the creation form
for the object Y contains a reference to the object X. A simpler
example would be when the creation form for the object X contains
a reference to X itself. Initialization forms are not subject to
any restriction against circular dependencies, which is the entire
reason that initialization forms exist. See the example of circular
data structures below.
The creation form for an object is always evaluated before the
initialization form for that object. When either the creation form or
the initialization form references other objects of user-defined types
that have not been referenced earlier in the COMPILE-FILE, the
compiler collects all of the creation and initialization forms. Each
initialization form is evaluated as soon as possible after its
creation form, as determined by data flow. If the initialization form
for an object does not reference any other objects of user-defined
types that have not been referenced earlier in the COMPILE-FILE, the
initialization form is evaluated immediately after the creation form.
If a creation or initialization form F references other objects of
user-defined types that have not been referenced earlier in the
COMPILE-FILE, the creation forms for those other objects are evaluated
before F, and the initialization forms for those other objects are
also evaluated before F whenever they do not depend on the object
created or initialized by F. Where the above rules do not uniquely
determine an order of evaluation, which of the possible orders of
evaluation is chosen is unspecified.
While these creation and initialization forms are being evaluated, the
objects are possibly in an uninitialized state, analogous to the state
of an object between the time it has been created by ALLOCATE-INSTANCE
and it has been processed fully by INITIALIZE-INSTANCE. Programmers
writing methods for MAKE-LOAD-FORM must take care in manipulating
objects not to depend on slots that have not yet been initialized.
It is unspecified whether LOAD calls EVAL on the forms or does some
other operation that has an equivalent effect. For example, the
forms might be translated into different but equivalent forms and
then evaluated, they might be compiled and the resulting functions
called by LOAD, or they might be interpreted by a special-purpose
interpreter different from EVAL. All that is required is that the
effect be equivalent to evaluating the forms.
COMPILE-FILE calls MAKE-LOAD-FORM on any object that is referenced as
a constant or as a self-evaluating form, if the object's metaclass is
STANDARD-CLASS, STRUCTURE-CLASS, any user-defined metaclass (not a
subclass of BUILT-IN-CLASS), or any of a possibly-empty
implementation-defined list of other metaclasses. COMPILE-FILE will
only call MAKE-LOAD-FORM once for any given object (compared with EQ)
within a single file.
It is valid for user programs to call MAKE-LOAD-FORM in other
circumstances, providing the argument's metaclass is not BUILT-IN-CLASS
or a subclass of BUILT-IN-CLASS.
Define a new function named MAKE-LOAD-FORM-USING-SLOTS, which takes
one required argument and one optional argument and returns two
values. This can be useful in user-written MAKE-LOAD-FORM methods.
The first argument is the object. The optional second argument is a
list of the names of the slots to preserve; it defaults to all of the
local slots. MAKE-LOAD-FORM-USING-SLOTS returns forms that construct
an equivalent object using MAKE-INSTANCE and SETF of SLOT-VALUE for
slots with values, or SLOT-MAKUNBOUND for slots without values, or
using other functions of equivalent effect.
MAKE-LOAD-FORM-USING-SLOTS returns two values, thus it can deal with
circular structures. MAKE-LOAD-FORM-USING-SLOTS works for any object
of metaclass STANDARD-CLASS or STRUCTURE-CLASS. Whether the result is
useful in an application depends on whether the object's type and slot
contents fully capture the application's idea of the object's state.
MAKE-LOAD-FORM of an object of metaclass STANDARD-CLASS or
STRUCTURE-CLASS for which no user-defined method is applicable signals
an error. It is valid to implement this either by defining default
methods on STANDARD-OBJECT and STRUCTURE-OBJECT that signal an error
or by having no applicable method for those classes.
Examples:
;; Example 1
(defclass my-class ()
((a :initarg :a :reader my-a)
(b :initarg :b :reader my-b)
(c :accessor my-c)))
(defmethod shared-initialize ((self my-class) ignore &rest ignore)
(unless (slot-boundp self 'c)
(setf (my-c self) (some-computation (my-a self) (my-b self)))))
(defmethod make-load-form ((self my-class))
`(make-instance ',(class-name (class-of self))
:a ',(my-a self) :b ',(my-b self)))
In this example, an equivalent instance of my-class is reconstructed
by using the values of two of its slots. The value of the third slot
is derived from those two values.
Another way to write the last form in the above example would have been
(defmethod make-load-form ((self my-class))
(make-load-form-using-slots self '(a b)))
;; Example 2
(defclass my-frob ()
((name :initarg :name :reader my-name)))
(defmethod make-load-form ((self my-frob))
`(find-my-frob ',(my-name self) :if-does-not-exist :create))
In this example, instances of my-frob are "interned" in some way.
An equivalent instance is reconstructed by using the value of the
name slot as a key for searching existing objects. In this case
the programmer has chosen to create a new object if no existing
object is found; alternatively she could have chosen to signal an
error in that case.
;; Example 3
(defclass tree-with-parent () ((parent :accessor tree-parent)
(children :initarg :children)))
(defmethod make-load-form ((x tree-with-parent))
(values
;; creation form
`(make-instance ',(class-of x) :children ',(slot-value x 'children))
;; initialization form
`(setf (tree-parent ',x) ',(slot-value x 'parent))))
In this example, the data structure to be dumped is circular, because
each parent has a list of its children and each child has a reference
back to its parent. Suppose make-load-form is called on one object in
such a structure. The creation form creates an equivalent object and
fills in the children slot, which forces creation of equivalent
objects for all of its children, grandchildren, etc. At this point
none of the parent slots have been filled in. The initialization form
fills in the parent slot, which forces creation of an equivalent
object for the parent if it was not already created. Thus the entire
tree is recreated at load time. At compile time, MAKE-LOAD-FORM is
called once for each object in the true. All of the creation forms
are evaluated, in unspecified order, and then all of the
initialization forms are evaluated, also in unspecified order.
;; Example 4
(defstruct my-struct a b c)
(defmethod make-load-form ((s my-struct))
(make-load-form-using-slots s))
In this example, the data structure to be dumped has no special
properties and an equivalent structure can be reconstructed
simply by reconstructing the slots' contents.
Rationale:
Only the programmer who designed a class can know the correct
way to reconstruct objects of that class at load time, therefore
the reconstruction should be controlled by a generic function.
Using EVAL as the interface for telling LOAD what to do provides
full generality.
MAKE-LOAD-FORM returns two values so that circular structures can
be handled. If CONSTANT-CIRCULAR-COMPILATION is rejected,
MAKE-LOAD-FORM will only return one value, although implementations
that make an extension to support circular constants will probably
also make the extension to accept two values from MAKE-LOAD-FORM.
The default for class objects and structures is to signal an error,
rather than picking some particular object reconstruction technique,
because no reconstruction technique is appropriate for all objects.
It only takes two lines of code, as in example 4, to instruct the
compiler to use the technique that most often has been suggested
as the default.
MAKE-LOAD-FORM has a natural resemblance to PRINT-OBJECT, as a hook
for the programmer to control the system's actions.
The order of evaluation rules for creation and initialization forms
eliminate the possibility of partially initialized objects in the
absence of circular structures, and reduce it to the minimum possible
in the presence of circular structures. This allows nodes in
non-circular structures to be built out of fully initialized subparts.
Current practice:
Symbolics Flavors has something like this, but under a different name.
The name Symbolics uses is not suitable for standardization.
JonL reports that Lucid is getting more and more requests for this.
Cost to Implementors:
This seems like only a few one-line changes in the compiled-code
file writer and reader. MAKE-LOAD-FORM-USING-SLOTS is a couple
dozen lines of code, assuming the presence of the CLOS metaobject
protocol or an implementation-dependent equivalent.
Cost to Users:
None.
Cost of non-adoption:
Serious impairment of the ability to use extended-type objects. Each
implementation will probably make up its own version of this as an
extension.
Performance impact:
None.
Benefits:
See Cost of non-adoption.
Esthetics:
No significant positive or negative impact.
Discussion:
It would be possible to define an additional level of protocol that
allows multiple classes to contribute to the reconstruction of an
object, combining initialization arguments contributed by each class.
Since a user can easily define that in terms of MAKE-LOAD-FORM without
modifying the Lisp system, it is not being proposed now.
Any type that has a read syntax is likely to appear as a quoted
constant or inside a quoted constant. Pathnames are one example, user
programs often define others. Also many implementations provide a way
to create a compiled-code file full of data (rather than compiled Lisp
programs), and such data probably include extended-type objects.
Moon supports this. David Gray and John Rose made major contributions
to the discussion that produced this improved version 2 proposal.
----- End Forwarded Messages -----
∂17-Mar-89 0009 X3J13-mailer Issue: REAL-NUMBER-TYPE (version 3)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 00:08:54 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 23:50:31 PST
Date: 16 Mar 89 23:49 PST
From: masinter.pa@Xerox.COM
Subject: Issue: REAL-NUMBER-TYPE (version 3)
To: x3J13@Sail.Stanford.EDU
Message-ID: <890316-235031-6996@Xerox>
!
Issue: REAL-NUMBER-TYPE
Forum: CLEANUP
References: Table 4-1.
Category: ADDITION
Edit history: 04-JAN-89, Version 1 by Bob Cassels, Don Sakahara, Kent Pitman,
and John Aspinall
08-JAN-89, Version 2 by Bob Cassels -- incorporate
Masinter's suggestion and make REAL a CLOS class
13-JAN-89, Version 3 by Cassels and Aspinall -- incorporate Marc LeBrun's
suggestions clarifying the relationship between CL
numeric type names and mathematical names
Status: For Internal Discussion
Problem Description:
There is no standard type specifier symbol for the CL type
'(OR RATIONAL FLOAT).
Proposal (REAL-NUMBER-TYPE:REAL):
Make REAL be a CL data type:
p.13 "Numbers"
Add: The NUMBER data type encompasses all of these kinds of
numbers. For convenience, there are names for some
subclasses of numbers. @i[Integers] and @i[ratios] are of
type RATIONAL. @i[Rational numbers] and @[floating-point
numbers] are of type REAL. @i[Real numbers] and @i[complex
numbers] are of type NUMBER.
Although the names of these types were chosen with the
terminology of mathematics in mind, the correspondences
are not always exact. Integers and ratios model the
corresponding mathematical concepts directly. Numbers
of the FLOAT type may be used to approximate real
numbers, both rational and irrational. The REAL type
includes all Common Lisp numbers which represent
mathematical real numbers, though there are
mathematical real numbers (irrational numbers)
which do not have an exact Common Lisp representation.
Only REAL numbers may be ordered using the <, >, <=,
and >= functions.
Compatibility note: The Fortran standard defines the term
"real datum" to mean "a processor approximation to the value
of a real number." In practice the Fortran "basic real" type
is the floating-point data type Common Lisp calls
SINGLE-FLOAT. The Fortran "double precision" type is
Common Lisp's DOUBLE-FLOAT. The Pascal "real" data type is
an "implementation-defined subset of the real numbers." In
practice this is usually a floating-point type, often what
Common Lisp calls DOUBLE-FLOAT.
A translation of an algorithm written in Fortran or Pascal
which uses "real" data usually will use some appropriate
precision of Common Lisp's FLOAT type. Some algorithms may
gain accuracy and/or flexibility by using Common Lisp's
RATIONAL or REAL types instead.
p.33 "Overlap, Inclusion, and Disjointness of Types":
Remove: The types RATIONAL, FLOAT, and COMPLEX are pairwise
disjoint subtypes of NUMBER.
Rationale: It might be thought that INTEGER and RATIO ...
Rationale: It might be thought that FIXNUM and BIGNUM ...
Add: The types RATIONAL and FLOAT are pairwise disjoint subtypes
of REAL.
The types REAL and COMPLEX are pairwise disjoint subtypes
of NUMBER.
Rationale: It might be thought that FIXNUM and BIGNUM should
form an exhaustive partition of the type INTEGER, that INTEGER
and RATIO should form an exhaustive partition of RATIONAL,
that RATIONAL and FLOAT should form an exhaustive partition of
REAL, and that REAL and COMPLEX should form an exhaustive
partition of NUMBER. These are all purposely avoided in order
to permit compatible experimentation with extensions to the
Common Lisp number system, such as the idea of adding explicit
representations of infinity or of positive and negative infinity.
p.43 Table 4-1 "Standard Type Specifier Symbols"
Add: REAL
p.49 "Type Specifiers that Abbreviate"
Add: (REAL low high)
Denotes the set of real numbers between low and high. ...
[As with RATIONAL and FLOAT.]
Make REAL a built-in CLOS class.
Proposal (REAL-NUMBER-TYPE:REALP):
Add a specific data type predicate REALP which tests for membership in
this type. [By analogy with NUMBERP.]
Test Case:
If a programmer wishes to test for "a number between 1 and 10", the
only current CL types would be '(or (rational 1 10) (float 1 10)) or
something like '(and numberp (not complexp) (satisfies range-1-10))
with (defun range-1-10 (real) (<= 1 real 10)). Both of these are
likely less efficient, and certainly less expressive than '(real 1 10).
Rationale:
Mathematics has a name for (OR RATIONAL FLOAT) -- it is "real".
This class is important because it is all the numbers which can be
ordered.
Throughout the "Numbers" chapter, the phrase "non-complex number" is
used.
MAX, MIN, p. 198 "The arguments may be any non-complex numbers."
CIS p. 207 "The argument ... may be any non-complex number."
Current Practice:
Probably nobody does this.
Cost to Implementors:
Some work is necessary to add this name. But since the underlying
type already exists the amount of work should be minimal.
Cost to Users:
Since this is an upward-compatible extension, it may be ignored by
users.
Cost of Non-Adoption:
Occasional inconvenience and/or inefficiency.
Benefits:
Mathematical clarity.
Ability to do CLOS method dispatch on the type.
Aesthetics:
As mentioned under "rationale," this would be a more concise way to
express a common programming idiom.
Discussion:
The name "non-complex number" is incorrect because future
implementations may wish to include numerical types which are neither
complex nor real. [e.g. pure imaginary numbers or quaternions]
The name "scalar" is incorrect because the mathematical concept of
scalar may indeed include complex numbers.
Fortran and Pascal use the name "real" to mean what CL calls
SINGLE-FLOAT. That should cause no significant problem, since a Lisp
program written using the type REAL will do mathematically what the
equivalent Fortran program would do. This is because Fortran's "real"
data-type is a subtype of the CL REAL type. The only differences
might be that the Lisp program could be less efficient and/or more
accurate.
A survey of several Fortran and Pascal books shows that the distinction
between INTEGER and REAL is that REAL numbers may have fractional
parts, while INTEGERs do not. Later discussions explain that REALs
cover a greater range. Much later discussions cover precision
considerations, over/underflow, etc. So the average Fortran or Pascal
programmer should be completely comfortable with the proposed Lisp
concept of REAL.
∂17-Mar-89 0817 X3J13-mailer Issue: COERCE-INCOMPLETE (Version 3)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 08:17:09 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 10:56:55 EST
Date: Fri, 17 Mar 89 10:57 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
Cc: masinter.pa@xerox.com, x3j13@sail.stanford.edu
In-Reply-To: <890316191820.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-Id: <19890317155747.8.BARMAR@OCCAM.THINK.COM>
Date: Thu, 16 Mar 89 19:18 EST
From: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
Date: Thu, 16 Mar 89 18:00 EST
From: Barry Margolin <barmar@Think.COM>
...
Problem with DEPRECATE: Didn't we specify that the way to convert a
lambda expression into a function object is to use (COERCE x 'FUNCTION)?
Or did we also define a new function that does this?
Re-read FUNCTION-TYPE. The thing Beckerle really wanted and finally
got (over my objection) was that COERCE did nothing `hard' ... What
it ended up being able to be do can be expressed by #'IDENTITY and
#'SYMBOL-FUNCTION.
(COERCE x 'FUNCTION) ==
(ETYPECASE X
(SYMBOL (SYMBOL-VALUE X))
(FUNCTION X))
I don't really think anything more needs to be provided, even if we
DEPRECATE coerce.
I can't find my copy of FUNCTION-TYPE, but I remember it being amended
to add coercion of lambda expressions to functions. Maybe my memory is
faulty, but I remember something like
(COERCE X 'FUNCTION) ==
(ETYPECASE X
(SYMBOL (SYMBOL-FUNCTION X))
(FUNCTION X)
((SATISFIES LAMBDA-EXP-P) (EVAL `(FUNCTION ,X))))
(DEFUN LAMBDA-EXP-P (X)
(AND (CONSP X) ; a non-null list
(EQ (CAR X) 'LAMBDA) ; beginning with LAMBDA
(NOT (NULL (CDR X))) ; with at least two elements
(LISTP (CADR X)))) ; argument list is a list
barmar
∂17-Mar-89 0834 X3J13-mailer Issue: LOCALLY-TOP-LEVEL (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89 08:34:33 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 559504; Fri 17-Mar-89 11:31:57 EST
Date: Fri, 17 Mar 89 11:31 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOCALLY-TOP-LEVEL (Version 2)
To: X3J13@sail.stanford.edu
References: <19890309233609.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890317163159.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
This is a cleanup committee issue. It could have been in the
compiler committee, but as it happens it ended up in the
cleanup committee.
Issue: LOCALLY-TOP-LEVEL
References: None
Related issues: EVAL-WHEN-NON-TOP-LEVEL, DECLARATION-SCOPE
Category: CLARIFICATION / ADDITION
Edit history: Version 1, 9-Mar-89, by Moon
Version 2, 16-Mar-89, by Moon, fix referenced proposal name
Problem description:
It is desirable to be able to wrap LOCALLY around one or more
top-level forms and have them continue to be treated as top-level
forms. Three examples of how this is useful:
- to put an OPTIMIZE or INLINE declaration into force around
several related forms.
- to put declarations into force around DEFCLASS, or any other
top-level form that lacks a syntax for embedded declarations.
- DECLARATION-SCOPE:NO-HOISTING, which passed in January,
removed the ability to use a DECLARE at the head of the body of a
DEFUN or DEFMACRO to make a declaration that applies to the entire
form, including the lambda-list. We are supposed to use LOCALLY
instead, but forms in the body of LOCALLY are not top-level,
and that changes the semantics of DEFMACRO.
Issue EVAL-WHEN-NON-TOP-LEVEL could not define LOCALLY to treat
its body as top-level forms, because only a special form can do
that and LOCALLY is a macro.
Proposal (LOCALLY-TOP-LEVEL:SPECIAL-FORM):
Change LOCALLY from a macro to a special form, and change the
definition of compiler processing (in EVAL-WHEN-NON-TOP-LEVEL)
so that when a LOCALLY form appears at top level the forms in
its body are processed at top level.
Examples:
(locally (declare (optimize (safety 3) (space 3) (speed 0)))
(defmacro frob (&environment e x y &optional (z (foo x y)))
(mumble x y z e)))
Without this proposal, this would have to be written
(defmacro frob (&environment e x y &optional (z (locally
(declare
(optimize
(safety 3)
(space 3)
(speed 0)))
(foo x y))))
(locally (declare (optimize (safety 3) (space 3) (speed 0)))
(mumble x y z e)))
Rationale:
Wrapping LOCALLY around a form should not change its semantics except
as specified by the declarations, hence the body of a top-level
LOCALLY should be top-level.
A macro cannot have a top-level body unless it expands into a special
form that has a top-level body; otherwise the macro invocation and
the macro expansion would not have identical semantics as top-level
forms. There is no available special form for LOCALLY to macroexpand
into (CLtL doesn't say, but presumably the intent was to expand into
a LET with an empty binding list).
Current practice:
The Zetalisp equivalent of LOCALLY worked to surround top-level forms,
because it was a macro that expanded into COMPILER-LET (stashing the
declarations in a special variable the compiler would look at). This
is of course the wrong way to do declarations, but it shows that the
idea was that you could wrap declarations around a bunch of top-level
forms.
Symbolics Genera 7.4.0 does not implement the proposal (but it does
not implement DECLARATION-SCOPE:NO-HOISTING either). I did
not survey any other implementations.
Cost to Implementors:
A half dozen lines of code in the compiler and a smaller amount
in the interpreter and any program-analyzing programs.
Cost to Users:
None.
Cost of non-adoption:
See the horrible example above.
Performance impact:
None.
Benefits:
More consistent language.
Esthetics:
Improved.
Discussion:
None.
∂17-Mar-89 0857 X3J13-mailer Re: Issue: COERCE-INCOMPLETE (Version 3)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 17 Mar 89 08:57:27 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA01151; Fri, 17 Mar 89 09:54:54 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA06800; Fri, 17 Mar 89 09:54:37 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903171654.AA06800@defun.utah.edu>
Date: Fri, 17 Mar 89 09:54:35 MST
Subject: Re: Issue: COERCE-INCOMPLETE (Version 3)
To: Barry Margolin <barmar@Think.COM>
Cc: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>, masinter.pa@xerox.com,
x3j13@sail.stanford.edu
In-Reply-To: Barry Margolin <barmar@Think.COM>, Fri, 17 Mar 89 10:57 EST
BarMar is right. I have a hardcopy of the FUNCTION-TYPE writeup that
was mailed on 4 Sep 88, with a note from Larry indicating that it's
the final version as passed at the June meeting. It includes
COERCE'ing of lambda expressions to functions as item 6b.
Personally, I don't think this is a valid argument for not getting rid
of COERCE, since it is easy to coerce a lambda expression to a function
using (EVAL `(FUNCTION ,x)).
-Sandra
-------
∂17-Mar-89 0854 X3J13-mailer Re: Issue: COERCE-INCOMPLETE (Version 3)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 08:53:52 PST
Received: from Salvador.ms by ArpaGateway.ms ; 17 MAR 89 08:48:52 PST
Date: 17 Mar 89 08:47 PST
From: masinter.pa@Xerox.COM
Subject: Re: Issue: COERCE-INCOMPLETE (Version 3)
In-reply-to: Barry Margolin <barmar@Think.COM>'s message of Fri, 17 Mar 89
10:57 EST
To: Barry Margolin <barmar@Think.COM>
cc: x3j13@sail.stanford.edu
Message-ID: <890317-084852-8321@Xerox>
I sent you a copy of FUNCTION-TYPE, as amended and passed. There was
discussion of an amendment to allow coercion of lambda expressions to
functions, but the decision at the June 88 X3J13 meeting was to not require
such coercions.
Most of the issues passed so far are available from arisia.xerox.com
clcleanup/passed. Some of the issues that were amended at the last meeting
haven't yet been stored 'as amended'. I hope to have them there in the next
few days, as well as copies of all of the 'pending' issues.
∂17-Mar-89 1041 X3J13-mailer Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 10:40:58 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 17 MAR 89 10:28:12 PST
Date: 17 Mar 89 10:25 PST
From: masinter.pa@Xerox.COM
Subject: Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3
To: x3J13@sail.stanford.edu
cc: masinter.pa@Xerox.COM
Message-ID: <890317-102812-1247@Xerox>
The notes from the January meeting said Accepted MORE-PERMISSIVE (v2),
as amended. Amendments made at the meeting added DELETE-PACKAGE and
DEFPACKAGE to the list of functions and removed the paragraph beginning
with the words "If IN-PACKAGE...".
I can't figure out where a package name *isn't* allowed in DEFPACKAGE
or where a package object would make sense. Are the notes incorrect,
or were we just to hasty?
Anyway, here's my guess at what we really meant to pass; I suppose
we can just vote this one in instead.
!
Issue: PACKAGE-FUNCTION-CONSISTENCY
References: 11.7 Package System Functions and Variables (pp182-188)
Category: CLARIFICATION/CHANGE
Edit history: 21-Oct-88, Version 1 by Pitman
12-Jan-89, Version 2 by Masinter (add MORE-PERMISSIVE option)
17-Mar-89, Version 3, by Masinter, MORE-PERMISSIVE as
amended & adopted at Jan 89 X3j13
Problem Description:
CLtL is vague about whether either or both of package or package name
are permissible in some cases.
Proposal (PACKAGE-FUNCTION-CONSISTENCY:MORE-PERMISSIVE):
Clarify that it is permissible to pass either a package object
or a package name (symbol or string) in the following situations:
- the :USE argument to MAKE-PACKAGE or IN-PACKAGE
- the first argument to IN-PACKAGE, FIND-PACKAGE, RENAME-PACKAGE
or DELETE-PACKAGE
- the second argument to INTERN, FIND-SYMBOL, UNINTERN
- the second argument to EXPORT, UNEXPORT, IMPORT,
SHADOWING-IMPORT, and SHADOW
- the first argument (or a member of the list which is the first
argument) to USE-PACKAGE or UNUSE-PACKAGE.
- the PACKAGE argument to DO-SYMBOLS.
- the PACKAGE argument to DO-EXTERNAL-SYMBOLS.
- the PACKAGE argument to DO-ALL-SYMBOLS.
If FIND-PACKAGE is given a package object as an argument, it simply
returns it.
Clarify that the functions PACKAGE-NAME, PACKAGE-NICKNAMES,
PACKAGE-USE-LIST, and PACKAGE-USED-BY-LIST are (at least conceptually)
accessors to package data structures and permit only package objects
as arguments.
Clarify that the function MAKE-PACKAGE permits only a package name
as an argument since it does not make sense to create an existing
package.
Clarify that package nicknames must always be expressed as package
names (symbols or strings) and may never be actual package objects.
In addition, require that PACKAGE-NAME, PACKAGE-NICKNAMES,
PACKAGE-USE-LIST, and PACKAGE-USED-BY-LIST to accept names,
too.
Examples:
(INTERN "FOO" "KEYWORD") => :FOO
(DEFVAR *FOO-PACKAGE* (MAKE-PACKAGE "FOO"))
(RENAME-PACKAGE "FOO" "FOO0")
(PACKAGE-NAME *FOO-PACKAGE*) => "FOO0"
(PACKAGE-NAME "SYS") might return "SYSTEM".
Rationale:
This makes things more consistent.
It also adds a generally useful capability.
Current Practice:
Symbolics Genera & Lucid permits strings as package names.
Symbolics Cloe does not permit strings as package names.
In Lucid FIND-PACKAGE and IN-PACKAGE require names.
Cost to Implementors:
Small.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Implementations would continue to vary gratuitously, leaving a potential
for portability problems.
Benefits:
The cost of non-adoption is avoided.
Aesthetics:
This makes things more regular, and so presumably more aesthetic.
Discussion:
Pitman ran across this problem while trying to port Macsyma to various
implementations. Discussion with other maintainers of portable programs
shows this is a common source of aggravation in portable code.
Since the pathname accessors all take namestrings or streams, one might
easily argue that it would be more consistent for PACKAGE-NAME,
PACKAGE-NICKNAMES, etc. to also take arguments of package names. After
all,
(PACKAGE-NAME "FOO") => "FOO"
is no stranger than
(NAMESTRING "JOE:fred.lisp") => "JOE:fred.lisp".
It would be possible to say that MAKE-PACKAGE took package objects as
arguments and just returned that package. That might have limited
usefulness on rare occassions, but mostly seemed too far out in left
field to bother suggesting it.
∂17-Mar-89 1223 X3J13-mailer **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89 12:23:14 PST
Received: from blacksox ([192.9.201.39]) by heavens-gate.lucid.com id AA00913g; Wed, 15 Mar 89 12:36:51 PST
Received: by blacksox id AA00297g; Wed, 15 Mar 89 12:40:06 PST
Date: Wed, 15 Mar 89 12:40:06 PST
From: Eric Benson <eb@lucid.com>
Message-Id: <8903152040.AA00297@blacksox>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
In-Reply-To: David A. Moon's message of Tue, 14 Mar 89 18:41 EST <19890314234118.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
Date: Tue, 14 Mar 89 18:41 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
This looks good so far. A few comments that might help you
along with the draft:
...
The :MACRO argument to AUGMENT-ENVIRONMENT shouldn't look like the CADR
of a MACROLET special form, instead it should be a list of lists (name
function). That is, the expander functions should be supplied in the
form of functions rather than in the form of the source text used by
MACROLET. Your rationale argues against this but I strongly believe
that the rationale is wrong. I wouldn't mind seeing the parsing portion
of MACROLET made available as a separate function.
A small point: Shouldn't this be an a-list of the form
(name . function) instead of a list of lists?
∂17-Mar-89 1214 CL-Cleanup-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89 12:14:37 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01413g; Wed, 15 Mar 89 23:32:00 PST
Received: by bhopal id AA11607g; Wed, 15 Mar 89 23:32:47 PST
Date: Wed, 15 Mar 89 23:32:47 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8903160732.AA11607@bhopal>
To: cl-cleanup@sail.stanford.edu
Cc: X3J13@Sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM's message of 15 Mar 89 05:13 PST <890315-051405-3472@Xerox>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Although I haven't had time to join the overly-lengthy discussion on this
matter, I did point out one particularly confusing direction -- that this
proposal to "fix" the function ADJUST-ARRAY has become a proposal to alter
the semantics of the type SIMPLE-ARRAY. Compare CLtL, p28, with the
sentence in the Rationale Section:
"Specifying the points left unspecified (requiring all simple arrays to be
non-adjustable and all adjustable arrays to be non-simple) would require
large changes to some implementations and would be of little benefit to
..."
and with an item in the Clarification section:
"a. Whether an array can be both simple and adjustable is unspecified."
[CLtL definition *does* specify it].
I suggested that a simple statement be added to the proposal as follows:
"This proposal does not attempt to alter the meaning of the type
SIMPLE-ARRAY in any way"
Moon expressed approval of adding that statement.
Altered semantics would mean that it is no longer a portable type. I
have sent out several trivially small examples that show this. Some
people have interpreted those examples as simply showing what happens
with "broken" code; but quite to the contrary, they show how code can be
"correct" on one implementation and "broken" on another ****** when the
definition of SIMPLE-ARRAY is allowed to vary between one implementation
and the other ******. Very carefully, CLtL spells out that implementations
may vary on the efficiency with which they implement SIMPLE-ARRAYS; but
nowhere does it provide for optional exclusion of some parts of the
definition thereof.
Also, I note that all of the discussion on the Cl-cleanup list was by
persons other than the half-dozen or so maintainers of "stock hardware"
compilers. I personally spoke with three others (not including myself)
at Hawaii, and we all have identical requirements for the type SIMPLE-ARRAY,
and identical resolve that it must not be changed. Our compilers will
continue to offer this C-level optimization capability; the only
question is whether or not the CL1989 Standard will be cognizant of it.
-- JonL --
∂17-Mar-89 1223 X3J13-mailer Issue ERROR TERMINOLOGY
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89 12:23:02 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01029g; Wed, 15 Mar 89 14:13:57 PST
Received: by challenger id AA12685g; Wed, 15 Mar 89 14:07:47 PST
Date: Wed, 15 Mar 89 14:07:47 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903152207.AA12685@challenger>
To: x3j13@sail.stanford.edu
Subject: Issue ERROR TERMINOLOGY
Is it the case that ``fatal'' is well-defined? If so, ``harmless'' is
simply something that is not fatal. According to my mathematics
education, that renders the term well-defined.
``Indeed, there is no way to invoke GC in Common Lisp and with a few
exceptions such as messages, GC must have NO side effects.''
Unsolicited messages can happen, and there is a proposal on the
cl-editorial table to render them harmless. If GC can have no side
effects, then why not state that and not wonder about unsolicited
messages? If we did that, then any Common Lisp that does print a
progress note is *out* of conformance.
Also, as I've said several times, rehashing, termination of processes,
progress messages, flushing IO buffers, closing streams, and a list of
possibly hundreds of things are side effects of GC that should be
guaranteed harmless (that is, not fatal).
``> Some things are not immediately harmful but may cause
> trouble later on.
Yes, lots of things are that way.''
The definition of fatal puts no time constraints on the fatality. Therefore,
neither does its negation.
``> By ``unpredictable but harmless'', I think we are in effect saying
> ``not completely unpredictable''. That is, we promise something but
> don't quite say what it is. For example, Lisp will presumably not
> break off and start playing chess. But maybe it's harmless to start
> playing chess.''
The beauty of a specification is knowing what not to say in order to
allow rational interpreters the freedom to interpret rationality now
and in the unpredictable future. There is considerable genius in the
fine line that Steele tread in CLtL on this. Does anyone rationally
think that a Common Lisp would be taken seriously that while GCing
broke out in a game of chess or an Irish gig? I refuse to seriously
debate with anyone who would use that as an example of something that
we must utter one word in the specification to prevent.
``As far as I can see, the only reasonable option is to specify
some range of possible consequences. The constraints, whatever
they may be, make it possible to reason about what the program
will do.''
The reason this won't easily work is that it presumes that we are able
to accurately predict future implementation techniques and even to
fully comprehend current ones. I'm sure that KMP or I could supply an
endless stream of new and bizarre cases that have to be explicitly
dealt with. (I single out KMP because he has uncanny creativity.)
But, I'll change the debate a little. I've claimed that ``harmless''
is well-defined if and only if ``fatal'' is well-defined or at least
defined well enough. So, to convince me that ``harmless'' should be
pitched, you must convince me that ``fatal'' must be pitched.
-rpg-
∂17-Mar-89 1223 X3J13-mailer issue SAFE-CODE, version 1
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89 12:22:54 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01090g; Wed, 15 Mar 89 14:31:11 PST
Received: by challenger id AA12754g; Wed, 15 Mar 89 14:25:03 PST
Date: Wed, 15 Mar 89 14:25:03 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903152225.AA12754@challenger>
To: cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
Subject: issue SAFE-CODE, version 1
According to my understanding of the dictionary definitions,
``unsafe'' means primarily ``the opposite or reversal of `safe' '' and
secondarily ``not safe.'' This coincides with Moon's reading.
Therefore, I propose we use the term ``nonsafe'' which clearly means
``not safe.'' This, coupled with the already very explicit definition
of ``unsafe,'' which explains that unsafe code might actually be safe,
should take care of his objection.
-rpg-
∂17-Mar-89 1246 X3J13-mailer Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 12:45:23 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 14:55:05 EST
Date: Fri, 17 Mar 89 14:46 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3
To: masinter.pa@xerox.com
Cc: x3J13@sail.stanford.edu
In-Reply-To: <890317-102812-1247@Xerox>
Message-Id: <19890317194641.7.BARMAR@OCCAM.THINK.COM>
Date: 17 Mar 89 10:25 PST
From: masinter.pa@xerox.com
Proposal (PACKAGE-FUNCTION-CONSISTENCY:MORE-PERMISSIVE):
Clarify that the functions PACKAGE-NAME, PACKAGE-NICKNAMES,
PACKAGE-USE-LIST, and PACKAGE-USED-BY-LIST are (at least conceptually)
accessors to package data structures and permit only package objects
as arguments.
...
In addition, require that PACKAGE-NAME, PACKAGE-NICKNAMES,
PACKAGE-USE-LIST, and PACKAGE-USED-BY-LIST to accept names,
too.
You can't have it both ways! Also, the grammar of the second one could
use improving.
barmar
∂17-Mar-89 1257 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 12:57:27 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 15:52:50 EST
Date: Fri, 17 Mar 89 15:53 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
To: Jon L White <jonl@lucid.com>
Cc: cl-cleanup@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: <8903160732.AA11607@bhopal>
Message-Id: <19890317205329.0.BARMAR@OCCAM.THINK.COM>
What happens in implementations that allow all arrays to be adjusted?
If you require that (typep x 'simple-array) implies (not
(adjustable-array-p x)), I see two possible resolutions: 1) such
implementations are not conforming; 2) the type SIMPLE-ARRAY is empty.
I find (1) distasteful, because non-adjustable arrays and the
SIMPLE-ARRAY type exist solely for the benefit of implementations that
need them, and this would require support of these concepts in
implementations that don't derive any benefit from them. I think (2)
makes the SIMPLE-ARRAY type pretty useless, since a portable program
can't expect anything to be of this type (FIXNUM had this problem until
we fixed it in Hawaii).
barmar
∂17-Mar-89 1251 CL-Compiler-mailer **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89 12:51:13 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 559802; Fri 17-Mar-89 15:48:20 EST
Date: Fri, 17 Mar 89 15:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
To: Eric Benson <eb@lucid.com>
cc: cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
In-Reply-To: <8903152040.AA00297@blacksox>
Message-ID: <19890317204812.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 15 Mar 89 12:40:06 PST
From: Eric Benson <eb@lucid.com>
Date: Tue, 14 Mar 89 18:41 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
The :MACRO argument to AUGMENT-ENVIRONMENT shouldn't look like the CADR
of a MACROLET special form, instead it should be a list of lists (name
function).
A small point: Shouldn't this be an a-list of the form
(name . function) instead of a list of lists?
Oh, I keep forgetting that some people have to worry about the efficiency
of conses versus lists. I don't care which it is.
∂17-Mar-89 1254 CL-Cleanup-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89 12:54:39 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 559814; Fri 17-Mar-89 15:51:33 EST
Date: Fri, 17 Mar 89 15:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
To: Jon L White <jonl@lucid.com>
cc: cl-cleanup@sail.stanford.edu, X3J13@Sail.stanford.edu
In-Reply-To: <8903160732.AA11607@bhopal>
Message-ID: <19890317205125.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 15 Mar 89 23:32:47 PST
From: Jon L White <jonl@lucid.com>
Although I haven't had time to join the overly-lengthy discussion on this
matter, I did point out one particularly confusing direction -- that this
proposal to "fix" the function ADJUST-ARRAY has become a proposal to alter
the semantics of the type SIMPLE-ARRAY.
Adding the discussion of SIMPLE-ARRAY was at *+*YOUR*+* request, JonL.
There is !!NO!! change to the semantics, as I thought you had agreed in
the last message you sent on the topic. If now you're taking that back
and saying that you still think what this proposal says is a change to
the semantics, okay, but I have yet to figure out why you think that or
what you think is changed.
∂17-Mar-89 1316 X3J13-mailer Issue DYNAMIC-EXTENT: a remark
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 13:15:31 PST
Received: from fafnir.think.com by Think.COM; Fri, 17 Mar 89 14:55:24 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 17 Mar 89 14:54:21 EST
Received: by verdi.think.com; Fri, 17 Mar 89 14:51:09 EST
Date: Fri, 17 Mar 89 14:51:09 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903171951.AA09006@verdi.think.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: gls@Think.COM, masinter.pa@xerox.com, X3J13@sail.stanford.edu
In-Reply-To: David A. Moon's message of Thu, 16 Mar 89 17:15 EST <19890316221519.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue DYNAMIC-EXTENT: a remark
Date: Thu, 16 Mar 89 17:15 EST
From: David A. Moon <Moon@stony-brook.scrc.symbolics.com>
Line-Fold: No
Date: Thu, 16 Mar 89 15:34:53 EST
From: Guy Steele <gls@Think.COM>
A "proper
part" of an object A is any object that is accessible at the beginning
of the scope of the declaration -only- by applying a function to A or to
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
a "proper part" of A. This means that any objects freshly allocated
during the construction of the initial value of the declared variable,
and not "saved" during the construction of that value, are "proper
parts" and can be allocated on a stack.
I believe that the words indicated above should be replaced by
"the extent of the binding for which the delaration was made".
That would change the meaning, since the declaration might not be attached
to a binding.
I am not certain that I understand the meaningful uses of this declaration
in cases where it is not attached to a binding.
The reference appears to be to a point in time. Scopes are in space;
the beginning of a scope is a character position in the text (or
something like that). Extents are in time. Is this what you meant?
You're right that there is something wrong with this wording. How about
if it said "at the beginning of execution of the forms in the scope of
the declaration"? Do declarations have extents? If so, could it say
"at the beginning of the extent of the declaration"?
I think you have to speak in terms of run-time instantiations
of executable code. Not sure.
--Guy
∂17-Mar-89 1356 CL-Compiler-mailer **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 13:54:27 PST
Received: from fafnir.think.com by Think.COM; Fri, 17 Mar 89 16:48:54 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 17 Mar 89 16:50:04 EST
Received: by verdi.think.com; Fri, 17 Mar 89 16:46:51 EST
Date: Fri, 17 Mar 89 16:46:51 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903172146.AA09535@verdi.think.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: eb@lucid.com, cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
In-Reply-To: David A. Moon's message of Fri, 17 Mar 89 15:48 EST <19890317204812.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
Date: Fri, 17 Mar 89 15:48 EST
From: David A. Moon <Moon@stony-brook.scrc.symbolics.com>
Date: Wed, 15 Mar 89 12:40:06 PST
From: Eric Benson <eb@lucid.com>
Date: Tue, 14 Mar 89 18:41 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
The :MACRO argument to AUGMENT-ENVIRONMENT shouldn't look like the CADR
of a MACROLET special form, instead it should be a list of lists (name
function).
A small point: Shouldn't this be an a-list of the form
(name . function) instead of a list of lists?
Oh, I keep forgetting that some people have to worry about the efficiency
of conses versus lists. I don't care which it is.
Well, don't forget PAIRLIS and ACONS, which make the CONS format
a little easier to use than the LIST format.
[Voice 1: AAAAHHHHH!!! No!!! Not FORMAT!!!]
Calm down; I meant it generically. Make that "organization".
[Voice 2: AUUGUGGHH! Not generics!]
--Guy
∂17-Mar-89 1426 X3J13-mailer CLTL II
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 14:24:50 PST
Received: from fafnir.think.com by Think.COM; Fri, 17 Mar 89 17:20:09 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 17 Mar 89 17:21:19 EST
Received: by verdi.think.com; Fri, 17 Mar 89 17:18:06 EST
Date: Fri, 17 Mar 89 17:18:06 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903172218.AA09852@verdi.think.com>
To: x3j13@sail.stanford.edu
Cc: gls@Think.COM
Subject: CLTL II
I have mailed copies of my current working draft of "CLTL II" to
nearly everyone on the X3J13 mailing list (defined to be the set of
mailing labels Bob Mathis sent me). Those of you in the US can expect
to receive them on Monday or Tuesday via UPS, except for the three of
you whose address is a P.O. Box, in which case you are at the mercy of
Priority SnailMail. I don't know how long it will take for
international delivery.
To keep the costs down, where two persons were at the same address or
organization, I sent only one copy; for three or more I generally sent
two copies. (In all I sent out 70 copies, at about 30 bucks each
including shipping.)
KMP points out that it would be a serious mistake for everyone to drop
everything and start reading this draft, and I agree. It is more
important to prepare for the upcoming meeting. Furthermore, I would
hate to see anyone burn out reading this less-than-authoritative draft
of a less-than-authoritative book and then not have the energy to give
the draft standard a careful reading as well.
You don't *have* to read it at all. If you don't have the time, then
use it as a doorstop, keep it as a souvenir, or give it to someone
like a graduate student.
I will be grateful for any feedback I can get, of course. I recommend
that you pay the most attention to my paraphrasing of and commentary
on issues with which you have been particularly involved, to make sure
I didn't goof it up. There is an index to the issues in the back that
may be helpful.
Some of the new material has nothing whatsoever to do with X3J13.
You may wish to check out the I/O and Numbers chapters, for example.
Digital Press will have a copy editor reading it for grammar and
punctuation, and I will be reading it carefully, so if your time
is limited you probably should concentrate on the conceptual level.
I am especially interested in feedback of the form "You're going about
this all wrong. Here's what you should do..."
Don't worry at all about fonts, spacing, or number of pages. What I
shipped to you today is merely 300-dots-per-inch draft quality with
the wrong fonts. I am meeting next week with the book designer at
Digital Press and we are going to work out what to do. I also have a
list of changes to make to my TeX macros that will systematically
improve the spacing and page break decisions.
--Guy
∂17-Mar-89 1541 CL-Cleanup-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 15:40:34 PST
Received: from fafnir.think.com by Think.COM; Fri, 17 Mar 89 16:23:16 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 17 Mar 89 16:24:05 EST
Received: by verdi.think.com; Fri, 17 Mar 89 16:20:53 EST
Date: Fri, 17 Mar 89 16:20:53 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903172120.AA09400@verdi.think.com>
To: jonl@lucid.com
Cc: cl-cleanup@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: Jon L White's message of Wed, 15 Mar 89 23:32:47 PST <8903160732.AA11607@bhopal>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Date: Wed, 15 Mar 89 23:32:47 PST
From: Jon L White <jonl@lucid.com>
...
Also, I note that all of the discussion on the Cl-cleanup list was by
persons other than the half-dozen or so maintainers of "stock hardware"
compilers. I personally spoke with three others (not including myself)
at Hawaii, and we all have identical requirements for the type SIMPLE-ARRAY,
and identical resolve that it must not be changed. Our compilers will
continue to offer this C-level optimization capability; the only
question is whether or not the CL1989 Standard will be cognizant of it.
I am very concerned about the stock hardware, but also very confused.
I understand that the stock-hardware implementors adamantly oppose
the proposed change, but I still have not seen a single convincing
example of why the proposed change would prevent them from accomplishing
the desired optimizations or why the proposed change would defeat
portability. I acknowledge that JonL has provided an example or two,
but I have not found them convincing. So either these examples are
wrong, or I am badly wedged; in either case I need further explanation.
--Guy
∂17-Mar-89 1555 X3J13-mailer Re: Issue: COERCE-INCOMPLETE (Version 3)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 15:55:11 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 18:48:21 EST
Date: Fri, 17 Mar 89 18:48 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Re: Issue: COERCE-INCOMPLETE (Version 3)
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
Cc: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>, masinter.pa@xerox.com,
x3j13@sail.stanford.edu
In-Reply-To: <8903171654.AA06800@defun.utah.edu>
Message-Id: <19890317234839.3.BARMAR@OCCAM.THINK.COM>
Date: Fri, 17 Mar 89 09:54:35 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Personally, I don't think this is a valid argument for not getting rid
of COERCE, since it is easy to coerce a lambda expression to a function
using (EVAL `(FUNCTION ,x)).
I disagree. Many of us would not have voted in favor of FUNCTION-TYPE
without the coercion. We wanted either a specific function or the
extension to COERCE. We specifically did not feel that the above idiom
should be used in any actual code; it merely serves as a good way of
describing the value that the coercion returns.
I'll go along with COERCE-INCOMPLETE:DEPRECATE if it is amended to
include a new function that coerces a lambda expression, symbol, or
function to a function. I'll even suggest a name: MAKE-FUNCTION
(unfortunately, FUNCTION is taken, so it can't follow the precedent of
naming a function that coerces to type T just T).
barmar
∂17-Mar-89 1600 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89 16:00:33 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA02088g; Fri, 17 Mar 89 15:53:13 PST
Received: by bhopal id AA19366g; Fri, 17 Mar 89 15:55:29 PST
Date: Fri, 17 Mar 89 15:55:29 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8903172355.AA19366@bhopal>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: cl-cleanup@sail.stanford.edu, X3J13@Sail.stanford.edu
In-Reply-To: David A. Moon's message of Fri, 17 Mar 89 15:51 EST <19890317205125.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
re: Adding the discussion of SIMPLE-ARRAY was at *+*YOUR*+* request, JonL.
Sorry, Dave, I only ever made a request to add precisely the one statement
that you have already now added -- that the proposal *does not* alter
the CLtL semantics of SIMPLE-ARRAY. What I critiqued were statements
of the proposal that under reasonable interpretation could be taken to
mean that the CLtL p.28 definition of SIMPLE-ARRAY is being abrogated.
At any rate, thanks for the one-line addition.
-- JonL --
∂17-Mar-89 1613 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89 16:13:52 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA02119g; Fri, 17 Mar 89 16:06:33 PST
Received: by bhopal id AA19436g; Fri, 17 Mar 89 16:08:50 PST
Date: Fri, 17 Mar 89 16:08:50 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8903180008.AA19436@bhopal>
To: barmar@Think.COM
Cc: cl-cleanup@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Fri, 17 Mar 89 15:53 EST <19890317205329.0.BARMAR@OCCAM.THINK.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
re: I find (1) distasteful, because non-adjustable arrays and the
SIMPLE-ARRAY type exist solely for the benefit of implementations that
need them, and this would require support of these concepts in
implementations that don't derive any benefit from them.
Barry, SIMPLE-ARRAY is certainly not the only concept in CLtL that exists
"solely for the benefit of implementations that [can really use it]". I
know that numerous array capabilities are present but not very useful
in Lucid Common Lisp primarily for compatiblity with Lisp Machine stuff.
That's the price to pay for portability. It just may be that we will have
to confess that we didn't succeed at portability in some areas of CL.
-- JonL --
∂17-Mar-89 1612 X3J13-mailer Re: Issue: COERCE-INCOMPLETE (Version 3)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 16:12:34 PST
Received: from Salvador.ms by ArpaGateway.ms ; 17 MAR 89 16:02:36 PST
Date: 17 Mar 89 15:57 PST
From: masinter.pa@Xerox.COM
Subject: Re: Issue: COERCE-INCOMPLETE (Version 3)
In-reply-to: masinter.pa's message of 17 Mar 89 08:47 PST
To: masinter.pa@Xerox.COM
cc: Barry Margolin <barmar@Think.COM>, x3j13@sail.stanford.edu
Message-ID: <890317-160236-2538@Xerox>
Sorry, I was confused when I sent that message. Yes, COERCE coerces lambda
expressions to functions. No, APPLY and FUNCALL do not (are not required
to)
do such coercions.
∂17-Mar-89 1623 X3J13-mailer Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3
Received: from YUKON.SCRC.Symbolics.COM (SCRC-YUKON.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89 16:23:09 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 439582; Fri 17-Mar-89 19:22:26 EST
Date: Fri, 17 Mar 89 19:20 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3
To: masinter.pa@Xerox.COM
cc: x3J13@sail.stanford.edu
In-Reply-To: <890317-102812-1247@Xerox>
Message-ID: <19890318002018.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: 17 Mar 89 10:25 PST
From: masinter.pa@Xerox.COM
The notes from the January meeting said Accepted MORE-PERMISSIVE (v2),
as amended. Amendments made at the meeting added DELETE-PACKAGE and
DEFPACKAGE to the list of functions and removed the paragraph beginning
with the words "If IN-PACKAGE...".
I can't figure out where a package name *isn't* allowed in DEFPACKAGE
or where a package object would make sense. Are the notes incorrect,
or were we just to hasty?
It wasn't my amendment, but I don't see why a package object should be
disallowed in any position in DEFPACKAGE other than the name or nickname
of the package being defined. I'll send a version that I think is correct
to CL-Cleanup and if no one disagrees it can be mailed to X3J13 to
supersede this one.
∂17-Mar-89 1656 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89 16:56:32 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 19:52:28 EST
Date: Fri, 17 Mar 89 19:53 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
To: Jon L White <jonl@lucid.com>
Cc: cl-cleanup@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: <8903180008.AA19436@bhopal>
Message-Id: <19890318005322.4.BARMAR@OCCAM.THINK.COM>
Date: Fri, 17 Mar 89 16:08:50 PST
From: Jon L White <jonl@lucid.com>
re: I find (1) distasteful, because non-adjustable arrays and the
SIMPLE-ARRAY type exist solely for the benefit of implementations that
need them, and this would require support of these concepts in
implementations that don't derive any benefit from them.
Barry, SIMPLE-ARRAY is certainly not the only concept in CLtL that exists
"solely for the benefit of implementations that [can really use it]". I
know that numerous array capabilities are present but not very useful
in Lucid Common Lisp primarily for compatiblity with Lisp Machine stuff.
That's the price to pay for portability. It just may be that we will have
to confess that we didn't succeed at portability in some areas of CL.
-- JonL --
The general rule has been that implementations that don't need (or don't
provide) these types of optimizations can safely ignore the language
features that support them. Some implementations can optimize array
access by knowing that the array can't be adjusted; other
implementations should not be required to remember this information if
they don't need it. Quoting from CLtL: "features that are useful only
on certain 'ordinary' or 'commercial' processors are avoided or made
optional."
Any feature of the language that provides access to facets of the
implementation allows somewhat non-portable code, meaning that it is
possible to write conforming code that produces different results in
different implementations. The simple program (PROGN
MOST-POSITIVE-FIXNUM) is conforming but produces many different results,
although the program (TYPEP MOST-POSITIVE-FIXNUM 'FIXNUM) is guaranteed
to return T in all conforming implementations. To paraphrase Moon, it
would be wonderful if all conforming programs were portable, but that's
unrealistic (it would be like expecting the grammar of a language to
only permit sensible sentences to be formed -- I suspect Godel's
Incompleteness Theorem comes into play here, pointing out that if the
grammar allows you to say everything you'd want to say, it must also
include some nonsense). The best I think we can do is provide enough
tools in the language to allow programs to detect implementation
differences and deal with them.
One thing that would help me is if you would post an example of code
that you feel is affected by this issue. I think you described such
things to me in words at the last meeting, but I (like GLS) am having a
hard time figuring out precisely what the problem is (I had the same
difficulty with the FIXNUM stuff that started the moby flame session in
the car on the way to the Japanese restaurant).
barmar
∂17-Mar-89 1758 X3J13-mailer too much mail!
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 17 Mar 89 17:58:23 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA21950; Fri, 17 Mar 89 18:56:10 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA07465; Fri, 17 Mar 89 18:56:08 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903180156.AA07465@defun.utah.edu>
Date: Fri, 17 Mar 89 18:56:07 MST
Subject: too much mail!
To: x3j13@sail.stanford.edu
Hey folks, I have a request. If you want to discuss an issue from one
of the subcommittees that was mailed to X3J13, please try to confine
the discussion to the appropriate subcommittee mailing list (or even
private mail to the person you're arguing with) instead of CC'ing all
of X3J13. Some of us have been getting hundreds of mail messages a
day and I (at least) don't have the time to follow all of the detailed
arguments on issues from other subcommittees anyway. I'd like to know
what the resolution of the problems is, but I don't really need to get
a blow-by-blow account in the meantime.
You will be getting such a summary (and some revised proposals) from
cl-compiler around the end of next week, by the way.
-Sandra
-------
∂17-Mar-89 2051 X3J13-mailer March meeting issues and sections
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 17 Mar 89 20:51:38 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
id AA16495; Fri, 17 Mar 89 10:21:57 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
id AA16495; Fri, 17 Mar 89 10:21:57 PST
Message-Id: <8903171821.AA16495@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
for skona%csilvax@hub.ucsb.edu; id AA16495; Fri, 17 Mar 89 10:21:57 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 17 Mar 89 13:00
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: March meeting issues and sections
Dear Members:
The issues and sections of the standard named below have been
mailed to the X3J13 mailing list electronically and by hardcopy.
Also, the sections are available in files named march-1.dvi (chapter 1),
march-2.dvi (sections 2.1 and 2.2), march-5.dvi (chapter5), and
march-27-ballot.dvi (all the above-listed sections). Those files are
on hudson.dec.com, as usual, and the sources are there.
These issues and sections will come to vote on March 30
during the X3J13 meeting.
An affirmative vote on a section of the standard means that you
agree with the contents of the section except possibly the following:
Indentation of examples.
Spelling and other typos.
Figure placement and design.
The physical presence of issue markers (these will be removed in
the final draft); the issue markers sometimes change the indentation.
In addition, sections of the standard that could be modified by issues
passed by X3J13 that haven't been included up to this point, or have
been incorrectly included or under-included, will change even after
an affirmative vote on the section.
You are seeing two items again that appeared on the letter ballot:
ERROR-TERMINOLOGY, and Section 1.8. These were significantly changed
as a result of comments and will therefore require reviewing and
revoting.
On the front cover of each chapter that is part of this mailing (chapters 1, 2,
and 5) is a list headed by Reviewed by:. The people on this list
have simply READ and COMMENTED ON the attached sections. The appearance
of their names on the list is not an indication
of their endorsement, although they may in fact endorse the section they
reviewed.
Following is a summary of each issue and section's review history:
ERROR-TERMINOLOGY -- This issue was last revised by RPG, Moon, and
Pitman, and now they seem to be satisfied with the wording. This proposal is
directly reflected in Section 5.1.
CONFORMANCE-POSITION -- See the discussion section of this issue.
The issue is directly reflected in Section 1.5.
SUBSETTING-POSITION -- This issue has received general approval.
EXTENSIONS-POSITION -- Some would prefer we remain mute on this
issue, but the fact is that we have to provide some sort of definition
of an extension since we use the term in the ERROR-TERMINOLOGY proposal
and in the standard.
EXTRA-SYNTAX -- This issue has not received much comment until
recently. A new revised version may be distributed at the meeting.
EXTRA-OPTIONAL-KEYWORD-ARGUMENTS -- Mixed reviews on this proposal.
EXTRA-RETURN-VALUES -- Not much discussion on this proposal although
it appears to be generally accepted. (Version 3, that is)
UNSPECIFIED-DATATYPES -- This proposal seems to be generally opposed.
UNSOLICITED-MESSAGES -- This issue has not received much comment
until recently. A revised version may be necessary.
MACRO-AS-FUNCTION -- Moon suggests that we just change the two
macros in question to functions (and skip the proposal?).
Sections 1.1-1.7 -- Some of these sections depend on the passage
of the previously-listed proposals. These sections have been reviewed
by numerous people and their comments have been included.
In addition, some suggestions for moving some of these sections
to an appendix are being entertained. That is covered in the TOC
issue which may undergo slight amendment at the meeting.
Sections 2.1-2.2 -- These sections have also been reviewed by
numerous people, and comments were included. The main unresolved
issues with section 2.2 seem to be as follows:
Lack of integration with CLOS and the Condition System.
Lack of a good definition of the type function.
These issues will most likely be resolved via clean-up proposals.
Sections 5.1-5.4 -- Section 5.1 is a rewrite of the concepts
part of the Condition System document approved by X3J13. It was reviewed in
detail by KMP, and also by Sandra Loosemore. The other sections were
reviewed by numerous people.
Section 1.8 -- This section was sent out with the letter ballot.
Although the section was intended to be non-detailed, it was apparently
much too vague to make it useful. It has been made slightly more detailed,
and whether or not it is at a suitable level will be decided by you.
A suggestion was made to move this section to an appendix.
If you need electronic copies of any of the issues, please let me know
(although they will be coming to you in hardcopy soon). If you have
any trouble accessing the standard sections, there are other ways
besides FTP and hardcopy for you to get the standard. If I don't know
you're having trouble, though, I can't help you resolve the problem.
Thanks in advance for all your review time so far. Your comments and
suggestions are immensely useful.
kathy chapman
∂17-Mar-89 2110 X3J13-mailer Issue: EXTRA-RETURN-VALUES (version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89 21:10:01 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 560236; Sat 18-Mar-89 00:07:10 EST
Date: Sat, 18 Mar 89 00:06 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTRA-RETURN-VALUES (version 3)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903160834.AA18011@decwrl.dec.com>
Message-ID: <19890318050654.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
I would support this if it were amended with a list of functions
that are explicitly allowed to have additional return values.
As a suggested rough cut at such a list, how about all the functions
described in chapters 16, 21, 22, 23, 24, and 25 of CLtL? These are
the functions that I would call "environment" rather than "language".
∂17-Mar-89 2304 X3J13-mailer Issue: PACKAGE-FUNCTION-CONSISTENCY (version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89 23:03:59 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 560302; Sat 18-Mar-89 02:00:54 EST
Date: Sat, 18 Mar 89 02:00 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PACKAGE-FUNCTION-CONSISTENCY (version 4)
To: X3J13@sail.stanford.edu
Message-ID: <19890318070046.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
This is a correction to some wording problems and inconsistencies
in version 3 that was mailed out yesterday.
!
Issue: PACKAGE-FUNCTION-CONSISTENCY
References: 11.7 Package System Functions and Variables (pp182-188)
Category: CLARIFICATION/CHANGE
Edit history: 21-Oct-88, Version 1 by Pitman
12-Jan-89, Version 2 by Masinter (add MORE-PERMISSIVE option)
17-Mar-89, Version 3, by Masinter, MORE-PERMISSIVE as
amended & adopted at Jan 89 X3j13
17-Mar-89, Version 4, by Moon, correct amended wording
Problem Description:
CLtL is vague about whether either or both of package or package name
are permissible in some cases.
Proposal (PACKAGE-FUNCTION-CONSISTENCY:MORE-PERMISSIVE):
Clarify that it is permissible to pass either a package object
or a package name (symbol or string) in the following situations:
- the :USE argument to MAKE-PACKAGE or IN-PACKAGE
- the first argument to IN-PACKAGE, FIND-PACKAGE, RENAME-PACKAGE
or DELETE-PACKAGE
- the second argument to INTERN, FIND-SYMBOL, UNINTERN
- the second argument to EXPORT, UNEXPORT, IMPORT,
SHADOWING-IMPORT, and SHADOW
- the first argument (or a member of the list which is the first
argument) to USE-PACKAGE or UNUSE-PACKAGE.
- all package-name arguments in DEFPACKAGE except for the name and
nicknames of the package being defined.
- the first argument to PACKAGE-NAME, PACKAGE-NICKNAMES,
PACKAGE-USE-LIST, or PACKAGE-USED-BY-LIST
- the PACKAGE argument to DO-SYMBOLS.
- the PACKAGE argument to DO-EXTERNAL-SYMBOLS.
- the PACKAGE argument to DO-ALL-SYMBOLS.
If FIND-PACKAGE is given a package object as an argument, it simply
returns it.
Clarify that the function MAKE-PACKAGE permits only a package name
as an argument since it does not make sense to create an existing
package.
Clarify that package nicknames must always be expressed as package
names (symbols or strings) and may never be actual package objects.
In the list above, IN-PACKAGE may be changed to SELECT-PACKAGE
if IN-PACKAGE-FUNCTIONALITY:NEW-MACRO passes.
Examples:
(INTERN "FOO" "KEYWORD") => :FOO
(DEFVAR *FOO-PACKAGE* (MAKE-PACKAGE "FOO"))
(RENAME-PACKAGE "FOO" "FOO0")
(PACKAGE-NAME *FOO-PACKAGE*) => "FOO0"
(PACKAGE-NAME "SYS") might return "SYSTEM".
Rationale:
This makes things more consistent.
It also adds a generally useful capability.
Current Practice:
Symbolics Genera & Lucid permit strings as package names.
Symbolics Cloe does not permit strings as package names.
In Lucid FIND-PACKAGE and IN-PACKAGE require names.
Cost to Implementors:
Small.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Implementations would continue to vary gratuitously, leaving a potential
for portability problems.
Benefits:
The cost of non-adoption is avoided.
Aesthetics:
This makes things more regular, and so presumably more aesthetic.
Discussion:
Pitman ran across this problem while trying to port Macsyma to various
implementations. Discussion with other maintainers of portable programs
shows this is a common source of aggravation in portable code.
It would be possible to say that MAKE-PACKAGE took package objects as
arguments and just returned that package. That might have limited
usefulness on rare occasions, but mostly seemed too far out in left
field to bother suggesting it.
∂18-Mar-89 0137 X3J13-mailer The Cleanup Issue Status List
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 18 Mar 89 01:37:09 PST
Received: from Semillon.ms by ArpaGateway.ms ; 18 MAR 89 01:34:10 PST
Date: 18 Mar 89 01:33 PST
From: masinter.pa@Xerox.COM
to: X3J13@sail.stanford.edu
Subject: The Cleanup Issue Status List
Message-ID: <890318-013410-3635@Xerox>
This is the complete list of Cleanup issues that are either:
passed: passed at *any* previous meeting, including Jan 89
pending: have been distributed for the March meeting
in progress: might possibly be distributed for the March meeting,
or that I think are worth pursuing.
Of course, some more might come up or be revived.
I think I have updated versions of all pending and passed
issues stored on arisia.xerox.com under the
clcleanup/pending
clcleanup/passed
directories respectively.
I'm pretty much unavailable (travelling, etc.) until the meeting.
I'll try to read my mail while on the road, but
it will be difficult to handle the quantity we've
seen in the last week.
Codes:
! released for Jan 89 meeting
+ passed
* need new version
!*: released, but I know we'll need a new version
+*: passed, but need to reconsider
!*: passed, but need a new version to reconsider
!
+ ADJUST-ARRAY-DISPLACEMENT
Version 4, 23-Nov-87
Status: passed, 1988
+ ADJUST-ARRAY-FILL-POINTER
Version 1, 15-MAR-88
Status: passed, 1988
! ADJUST-ARRAY-NOT-ADJUSTABLE
Synopsis: ADJUST-ARRAY on array made with :ADJUSTABLE NIL: "an error"?
Version 4, 11-Jan-89, Released 12-Jan-89
Status: Accepted with amendments Jan 89 X3J13
Comments: amendment had wording problem.
Version 8, 11-Mar-89, Released 15-Mar-89
Status: ready for vote
+ APPLYHOOK-ENVIRONMENT
Synopsis: remove (useless) env argument to applyhook
Version 2, 10-Jan-89, Released 10-Jan-89
Status: Passed Jan-89 X3J13
+ AREF-1D
14-NOV-87, Version 7
Status: Passed, 1988?
+ ARGUMENTS-UNDERSPECIFIED
Synopsis: Clarify various ranges missing from CLtL
Version 4, 21-Sep-88, Released 4 Dec 88
Status: Passed Jan 89 X3J13
+ ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS
Synopsis: What do array element-type declarations mean?
Version 9, 31-Oct-88, Released 5 Dec 88
Status: Passed Jan 89 X3J13
+ ASSOC-RASSOC-IF-KEY
Version 4, 23-NOV-87
Status: Passed, 1988?
! BREAK-ON-WARNINGS-OBSOLETE
Synopsis: deprecate *BREAK-ON-WARNINGS* because of *BREAK-ON-SIGNALS*
Version 1, 07-Mar-89, Released 15-Mar-89
Comment: leaves out a case
Status: ready for vote
! CLOS-CONDITIONS
Version 4, 10-Mar-89
Comments: define metaclass of conditions?
Status: pending
+ CLOSE-CONSTRUCTED-STREAMS
Synopsis: What does it mean to CLOSE a constructed stream?
Version 2, 12-Jan-89, Released 12-Jan-89
Status: Proposal ARGUMENT-STREAM-ONLY passed Jan 89 X3J13
!+ CLOSED-STREAM-OPERATIONS
Synopsis: What operations are legal on closed streams?
Version 5, 5-Dec-88, released 5-Dec-88
Status: amended at meeting
Version 7, 14-Feb-89
Status: Passed, as amended, Jan 89 X3J13
Comment: amendment bad; reconsider version 5.
say that INPUT-STREAM-P and OUTPUT-STREAM-P
are undefined on closed streams?
! COERCE-INCOMPLETE
Synopsis: Extend COERCE
Version 3, 7-Mar-89, Released 14-Mar-89
Status: ready for voting
+ COLON-NUMBER
Synopsis: :123 is an error
22-OCT-87, Version 1
Status: Passed, 1988?
+ COMPILER-WARNING-STREAM
Version 6, 5-JUN-87
Status: Passed, 1988?
+ COMPLEX-ATAN-BRANCH-CUT
Synopsis: tweak upper branch cut in ATAN formula
Version 1, 13-Dec-88, Released 10-Jan-89
Status: Passed Jan 89 X3J13
!* CONDITION-RESTARTS
Synopsis: can't know whether restart is associated with signalling
Version 1, 18-Jan-89, released 16-Mar-89
Comment: (proposed amendments)
Status: need new version
+ CONTAGION-ON-NUMERICAL-COMPARISONS
Version 1, 14-Sep-88, Released 6 Oct 88
Status: passed, Jan 89 X3J13
! COPY-SYMBOL-COPY-PLIST
Version 1, 10-Jan-89, released 16-Mar-89
Status: ready for vote
! COPY-SYMBOL-PRINT-NAME
Version 2, 15-Mar-89, released 16-Mar-89
Status: ready for vote
+ DATA-TYPES-HIERARCHY-UNDERSPECIFIED
4-SEP-88 Version 2
Status: Passed, 1988?
+ DECLARATION-SCOPE
Version 4, 15-Nov-88, Released 9-Dec-88
Status: NO-HOISTING passed Jan 89 X3J13
+ DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES
Version 3, 13-Jan-89
Status: passed, Jan 89 X3J13
+ DECLARE-FUNCTION-AMBIGUITY
Version 4, 5-Dec-88, Released 5-Dec-88
Status: passed, Jan 89 X3J13
+ DECLARE-MACROS
5-FEB-88, Version 3
Status: Passed, 1988?
+ DECLARE-TYPE-FREE
Version 10, 12-Jan-89
Status: proposal LEXICAL passed Jan 89 X3J13
+ DECODE-UNIVERSAL-TIME-DAYLIGHT
Version 2, 30-Sep-88, Released 6 Oct 88
Status: Passed, Jan 89 x3j13
* DEFMACRO-LAMBDA-LIST
Version 2, 17-Mar-89
Status: ready for release?
+ DEFPACKAGE
Version 7, 2-Nov-88, Released 5 Dec 88
Comment: clarify "at variance" in editorial work?
Status: Passed, Jan 89 X3J13
+ DEFSTRUCT-CONSTRUCTOR-KEY-MIXTURE
Version 3, 8-Jan-89, Released 11-Jan-89
Status: Passed, Jan 89 X3J13
+ DEFSTRUCT-DEFAULT-VALUE-EVALUATION
Version 1, 5/13/88
Status: Passed, 1988
+ DEFSTRUCT-PRINT-FUNCTION-INHERITANCE
Version 3, 7 Dec 88, Released 12-Dec-88
Status: Passed, Jan 89 X3J13
+ DEFSTRUCT-REDEFINITION
Synopsis: what happens if you redefine a DEFSTRUCT?
Version 3, 6-Feb-89
Status: Passed (as amended) Jan 89 X3J13
+ DEFSTRUCT-SLOTS-CONSTRAINTS-NAME
Version 5, 12-Jan-89
Status: Passed, Jan 89 X3J13
+ DEFSTRUCT-SLOTS-CONSTRAINTS-NUMBER
Version 1, 5/13/88
Status: Passed, 1988
+ DEFVAR-DOCUMENTATION
23-NOV-87, Version 2
Status: Passed, 1988?
+ DEFVAR-INIT-TIME
29-MAR-87, Version 2
Status: Passed, 1988?
+ DEFVAR-INITIALIZATION
Version 4 5-JUN-87
Status: Passed, 1988?
+ DESCRIBE-INTERACTIVE
Version 4, 15-Nov-88, Released 7-Dec-88
Synopsis: can DESCRIBE ask user a question?
Status: Proposal NO passed Jan 89 X3J13
! DESCRIBE-UNDERSPECIFIED
Version 1, 10-Mar-89, Released 16-Mar-89
Synopsis: making DESCRIBE generic was wrong; fix
status: ready for vote
!* DESTRUCTURING-BIND
Version 2, 25-Jan-89, Released 16-Mar-89
Synopsis: add DESTRUCTURING-BIND macro
Status: might need new version before vote
+ DISASSEMBLE-SIDE-EFFECT
Version 3 1/21/88
Status: Passed, 1988
+ DO-SYMBOLS-DUPLICATES
Version 3 23-NOV-87
Status: Passed, 1988?
+ DOTTED-MACRO-FORMS
Version 3, 15-Nov-88, Released 7-Dec-88
Status: passed, Jan 89 X3J13
+ DRIBBLE-TECHNIQUE
14-FEB-88, Version 2
Status: Passed, 1988?
! DYNAMIC-EXTENT
Version 3, 11-Jan-89, released 16-Mar-89
Comments: still some holes
Status: ready for vote?
+ EQUAL-STRUCTURE
Version 6, 11-Jan-89, Released 12-Jan-89
Status: Passed with amendments
Version 7, 15-Mar-89
Status: Passed Jan 89 X3J13 as amended.
* EQUALP-GENERIC
Version 1, 28-Feb-89
Synopsis: make EQUALP generic function
Comments: Various problems being worked on
Status: ** NEED NEW VERSION ***
* ERROR-CHECKING-IN-NUMBERS-CHAPTER
Version 1, 6-Mar-89
Synopsis: define 'should signal', 'might signal' for number fns
Status: ** NEED NEW VERSION **
! ERROR-NOT-HANDLED
Version 1, 25-Sep-88, Released 6-Oct-88 and 14-Mar-89
Status: ready for vote
+ EVAL-OTHER
8-JUN-88, Version 2
Status: Passed, 1988?
! EXIT-EXTENT
Version 6, 8-Jan-89, distributed at Jan89 X3J13
Rereleased 16-Mar-89
Status: tabled Jan89; ready for vote
+ EXPT-RATIO
Version 3, 31-Oct-88, Released 7 Dec 88
Status: passed, Jan 89 X3J13
+ FIXNUM-NON-PORTABLE
Version 4, 7-Dec-88, Released 12-Dec-88
Version 6, 17-Mar-89, as amended
Status: Passed, Jan 89 X3J13, as amended
+ FLET-DECLARATIONS
Version 2, 2 FEB 88
Status: Passed, 1988?
+ FLET-IMPLICIT-BLOCK
Version 6 5-JUN-87
Status: Passed, 1988?
+ FORMAT-ATSIGN-COLON
Version 4 5-JUN-87
Status: Passed, 1988?
+ FORMAT-COLON-UPARROW-SCOPE
Version 3, 5 FEB 88
Status: Passed, 1988?
+ FORMAT-COMMA-INTERVAL
Version 2, 15-JUN-87
Status: Passed, 1988?
+ FORMAT-E-EXPONENT-SIGN
Version 2, 2 Oct 88, Released 6 Oct 88
Status: Passed, Jan 89 X3J13
+ FORMAT-OP-C
11-JUN-87, Version 5
Status: Passed, 1988?
* FORMAT-PLURALS
Synopsis: remove ~P, add ~:@[singular~;plural~]
Status: no proposal
+ FORMAT-PRETTY-PRINT
Version 7, 15 Dec 88, Released 7 Dec 88
Comments: passed, Jan 89 X3j13
+ FUNCTION-CALL-EVALUATION-ORDER
Version 1, 22-MAR-88
Status: Passed, 1988
! FUNCTION-COERCE-TIME
Synopsis: When does SYMBOL-FUNCTION happen in MAPCAR?
Version 2, 16-sep-88, Released 8-Oct-88
Re-released: 16-Mar-89
Status: ready for vote?
+ FUNCTION-COMPOSITION
Synopsis: Add new functions
Version 5, 10-Feb-89
Status: Passed (as amended) Jan 89 X3J13
maybe this was passed as amendment to TEST-NOT-IF-NOT instead
+ FUNCTION-DEFINITION
Version 3, 10-Feb-89
Status: Passed (as amended) Jan 89 X3J13
! FUNCTION-NAME
Comment: renaming of SETF-FUNCTION-VS-MACRO, SETF-PLACES
SETF-FUNCTION-VS-MACRO
Version 3, 4-Nov-87, Released Nov 87
SETF-PLACES
Version 1, 11-Nov-88, Released 9-Dec-88
FUNCTION-NAME
Version 1, 27-Jan-89, Released 16-Mar-89
Status: ready for vote
+ FUNCTION-TYPE
Version 12, 4-SEP-88
Status: Passed, June 1988 X3J13, as amended
+ FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS
Synopsis: Change semantics of argument types in function declarations
Version 3, 7-Dec-88, Released 12-Dec-88
Status: Passed, Jan 89 X3J13
+ FUNCTION-TYPE-KEY-NAME
Version 3, 13-FEB-88
Status: Passed, 1988
+ FUNCTION-TYPE-REST-LIST-ELEMENT
Version 5, 14-Nov-88, Released 8-Dec-88
Status: Passed, Jan 89 X3J13
! GENSYM-NAME-STICKINESS
Synopsis: no side effects if optional arg supplied
Version 1, 14-Feb-89, Released 14-Mar-89
Status: comments
Version 2, 16-Mar-89
Status: ready for release?
+ GET-MACRO-CHARACTER-READTABLE
Version 3, 11-Feb-89
Status: Passed (as amended) Jan 89 X3J13
+ GET-SETF-METHOD-ENVIRONMENT
Version 5 13-JUL-87
Status: Passed, 1988?
! HASH-TABLE-ACCESS
Synopsis: Add new accessors for hash-table properties
Version 1, 13-Sep-88 released 8-Oct-88
Version 2, 13 Oct 88, released 16-Mar-89
status: vote
+ HASH-TABLE-PACKAGE-GENERATORS
Version 7, 8-Dec-88, Released 9-Dec-88
Comments: The test-package-iterator example has the values
from the generator in the wrong order.
Status: passed, Jan 89 X3J13
* HASH-TABLE-PRINTED-REPRESENTATION
Version 2, 8-Jun-88
Comments: Use #S(ARRAY ...), #S(HASH-TABLE...), #S(PATHNAME...)?
Status: need new proposal
+ HASH-TABLE-TESTS
Version 2, 8-Dec-88, Released 8 Dec 8 8
Status: passed Jan 89 X3J13
+ IEEE-ATAN-BRANCH-CUT
Version 2, 11-Jan-89, Released 11-Jan-89
Status: passed, Jan 89 X3J13
* IGNORE-VARIABLE
Synopsis: default (IGNORE IGNORE)
Version 1, 6-Feb-89
+ IMPORT-SETF-SYMBOL-PACKAGE
Version 5 ??-MAY-87
Status: Passed, 1988?
! IN-PACKAGE-FUNCTIONALITY
Version 4, 12-Dec-88, Released 12-Dec-88
Status: tabled
Version 8, 15-Mar-89, Released 15-Mar-89
Status: ready for vote
+ KEYWORD-ARGUMENT-NAME-PACKAGE
8-NOV-87, Version 8
Status: Passed, 1988?
+ LAST-N
12-MAR-88, Version 2
Status: Passed, 1988?
+ LCM-NO-ARGUMENTS
Version 1, 17 Oct 88, Released 8 Dec 88
Status: passed, Jan 89 X3J13
! LISP-PACKAGE-NAME
Synopsis: change LISP to COMMON-LISP to avoid CLtL confusion
Version 1, 22 Dec 88, Released 11-Jan-89
Status: tabled; version 1 still ready for vote
! LISP-SYMBOL-REDEFINITION
Version 5, 22-Nov-88, Released 8 Dec 88
Comments: Don't like (DEFVAR CAR ...) example
14: Like simpler "Redefining any documented
definition on a symbol in the LISP package -- such as variables,
functions, constants, properties and property-lists, etc -- is
undefined, except for the explicitly allowed cases (e.g. dynamic
binding of variables)."
Status: tabled; version 5 still ready for vote
! LOAD-OBJECTS
Synopsis: Provide a way to allow defstruct/defclass objects in compiled files
Version 3, 9-Mar-89, released 16-Mar-89
Status: ready for vote?
! LOAD-TRUENAME
Synopsis: Make default pathname for LOAD inside LOAD same?
Version 1, 13-Mar-89, Released 16-Mar-89
Status: ready for vote
! LOCALLY-TOP-LEVEL
Version 2, 16-Mar-89, released 17-Mar-89
Status: ready to vote
! LOOP-AND-DISCREPANCY
Version 1, 15-Mar-89, released 16-Mar-89
status: ready for vote
+ MACRO-FUNCTION-ENVIRONMENT
Version 2, 8-JUN-88
Status: Passed, 1988
* MACRO-SPECIAL-FORMS
Synopsis: macros => implementation-dependent special forms doesn't work
Status: *** NEED PROPOSAL SUBMITTED ****
+ MAKE-PACKAGE-USE-DEFAULT
Version 2, 8 Oct 88, Released 12-Dec-88
Version 3, 16-Mar-89
Status: Passed, Jan 89 X3J13 as amended
! MAKE-STRING-FILL-POINTER
Synopsis: extend MAKE-STRING to take a fill-pointer?
Version 1, 20-Oct-88, released 16-Mar-89
Status: ready for vote
+ MAPPING-DESTRUCTIVE-INTERACTION
Version 2, 09-Jun-88, Released 8 Oct 88
Synopsis: [don't] define interaction of DELETE on MAPCAR'd list.
Status: passed, Jan 89 X3J13
+ NTH-VALUE
Version 4, 8-Dec-88, Released 8 Dec 88
Comment: amended to clarify when index out of range
Version 5, 17-Mar-89
Status: passed, as amended
+ PACKAGE-CLUTTER
Version 6, 12-Dec-88, Released 12-Dec-88
Comments: Accepted, with amendment
Version 7, 17-Mar-89
Status: Passed, Jan 89 X3J13, as amended
+ PACKAGE-DELETION
Version 5, 21 nov 88, Released 8 Dec 88
Comments: Minor glitches? Remove the description of "correctable" error to be signalled and
handled.
Status: passed, Jan 89 X3J13
!+ PACKAGE-FUNCTION-CONSISTENCY
Synopsis: allow strings for package arg everywhere uniformly
Version 2, 12-Jan-89, Released 12-Jan-89
Comment: Accepted MORE-PERMISSIVE with amendments
Version 3, 17-Mar-89, released 17-Mar-89
Status: vote to accept wording as intent of amendment
* PATHNAME-CANONICAL-TYPE
Synopsis: allow canonical :SOURCE-LISP to MAKE-PATHNAME;
require PATHNAME-TYPE to return same?
Version 1, 07-Jul-88
Comments: only add the :TYPE :SOURCE-LISP, not PATHNAME-CANONICAL-TYPE?
Status: => "pathname" committee?
* PATHNAME-LOGICAL
Synopsis: add logical pathnames (pathnames for an imaginary portable
file system, which get translated by site-dependent translations into
physical pathnames on an actual file system)
Status: no proposal yet
* PATHNAME-PRINT-READ
Synopsis: Print pathnames like #P"asdf"?
Version 1, 21-Oct-88
Comments: Numerous, pro, con. Print like #S(pathname ...)?
Status: *** NEED NEW VERSION ***
+ PATHNAME-STREAM
Version 6 14-NOV-87
Status: Passed, 1988?
+ PATHNAME-SYMBOL
Version 5 5-FEB-88
Status: Passed, 1988?
* PATHNAME-SUBDIRECTORY-LIST
Synopsis: How to deal with subdirectory structures in pathname functions
Version 3, 29-Dec-88
Comments: typos and proposed simplifications
Status: *** NEED NEW VERSION ***
* PATHNAME-SYNTAX-ERROR-TIME
Synopsis: when are errors in pathnames detected?
Version 1, 7-Jul-88
Comments: various
Status: need new version? ==> ERRORS-IN-FILE-CHAPTERS?
+ PATHNAME-UNSPECIFIC-COMPONENT
Synopsis: More extensions to :UNSPECIFIC
Version 1, 29-Dec-88, Released 12-Jan-89
Version 2, 17-Mar-89
Status: Passed, Jan 89 X3j13, as amended
+ PEEK-CHAR-READ-CHAR-ECHO
Version 3, 8-Oct-88, Released 8 Oct 88
Synopsis: PEEK-CHAR, READ-CHAR on streams made by MAKE-ECHO-STREAM
Status: Passed, Jan 89 X3J13
* PRETTY-PRINT-INTERFACE
Version 3, 15-Mar-89
Synopsis: standardize interface to prettyprinter
Status: Need new version
+ PRINC-CHARACTER
29-APR-87, Version 2
Status: Passed, 1988?
* PRINT-CIRCLE-SHARED
Synopsis: does *PRINT-CIRCLE* cause shared structure to print with #=?
Status: Not submitted yet ** NEED WRITEUP **
+ PRINT-CIRCLE-STRUCTURE
Version 3, 20 Sep 88, Released 8 Oct 88
Comments: Accepted, with amendment
Version 4, 17-Mar-89
Status: Passed, Jan 89 X3J13, as amended
! PROCLAIM-LEXICAL
Version 9, 8-Dec-88, Released 12-Dec-88
Synopsis: add LEXICAL proclaimation
Comments: lengthy mail; amendments at Jan meeting
Status: tabled, vote on version 9 (w/o amendments)
+ PUSH-EVALUATION-ORDER
Version 5, 25-NOV-87
Status: Passed, 1988?
+ RANGE-OF-COUNT-KEYWORDS
Version 3, 9-Oct-88, Released 14-Oct-88
Status: passed, Jan 89 X3J13
+ RANGE-OF-START-AND-END-PARAMETERS
Version 1, 14-Sep-88, Released 7 Oct 88
Status: passed, Jan 89 X3J13
* READ-CASE-SENSITIVITY
Synopsis: Allow readtables to be case sensitive
Comments: use function or keyword?
Status: need new version
* READ-DELIMITED-LIST-EOF
Synopsis: eof in read deliminted list signals an error
Status: awaiting submission
! REAL-NUMBER-TYPE
Synopsis: add REAL = (OR RATIONAL FLOAT) & range
Version 3, 13-Jan-89, released 16-Mar-89
Status: vote?
+ REDUCE-ARGUMENT-EXTRACTION
Version 3 13-FEB-88
Status: Passed, 1988?
!* REMF-DESTRUCTION-UNSPECIFIED
Synopsis: Specification of side-effect behavior in CL
Version 4, 29-Nov-88, Released 12-Jan-89
Status: straw vote in favor of this, BarMar will make amendments
Version 5, 15-Mar-89
Comment: needs a little work
Status: *** NEARLY READY -- NEED NEW VERSION ****
+ REQUIRE-PATHNAME-DEFAULTS
Version 6, 9 Dec 88, Released 09 Dec 88
Status: passed, Jan 89 X3j13
+ REST-LIST-ALLOCATION
Version 3, 12-Dec-88, Released 12-Dec-88
Status: proposal MAY-SHARE passed, Jan 89 X3J13
+ RETURN-VALUES-UNSPECIFIED
Version 6, 9 Dec 88, Released 9-Dec-88
Status: passed, Jan 89 X3J13
+ ROOM-DEFAULT-ARGUMENT
Version 1, 12-Sep-88, Released 8 Oct 88
Status: passed, Jan 89 X3J13
* SETF-MULTIPLE-STORE-VARIABLES
Synopsis: Allow multiple "places" in SETF stores
Version 1, 5-Dec-88
Status: *** NEED NEW VERSION ****
+ SETF-SUB-METHODS
Version 5, 12-Feb-88, Released 8 Oct 88
Synopsis: careful definition of order inside (SETF (GETF ...) ...)
Status: passed, Jan 89 X3J13
+ SHADOW-ALREADY-PRESENT
Version 4 10-NOV-87
Status: Passed, 1988?
+ SHARPSIGN-PLUS-MINUS-PACKAGE
Version 3 14-NOV-87
Status: Passed, 1988?
+ SPECIAL-TYPE-SHADOWING
Synopsis: intersection of types when proclaimed special has local type
declaration
Version 1, 4-Nov-88, released 11-Jan-89
Status: passed, Jan 89 X3J13
+ STANDARD-INPUT-INITIAL-BINDING
Version 8, 8 Jul 88, Released 7 Oct 88
Status: passed, Jan 89 X3J13
+ STEP-ENVIRONMENT
Version 3, 20-Jun-88, Released 7 Oct 88
Version 4, 17-Mar-89
status: Passed, Jan 89 X3J13, as amended
+ STREAM-ACCESS
Version 2, 30-Nov-88, Released 9 Dec 88
Status: ADD-TYPES-ACCESSORS passed, Jan 89 X3J13
+ SUBSEQ-OUT-OF-BOUNDS
29-MAR-88 Version 2
Status: Passed, 1988?
* SUBTYPEP-ENVIRONMENT
Version 1, 2-Jan-89
Status: ** missing writeup ***
+ SUBTYPEP-TOO-VAGUE
Version 4, 7-Oct-88, Released 7 Oct 88
Status: passed, Jan 89 X3J13
+ SYMBOL-MACROLET-DECLARE
Version 2, 9-Dec-88, Released 9 Dec 88
Status: passed, Jan 89 X3J13
!+ SYMBOL-MACROLET-SEMANTICS
Version 5, 30-Nov-88, Released 9 Dec 88
Status: Passed, Jan 89 X3J13
Version 6, 14-Mar-89, released 16-Mar-89
Status: ready for vote
+ TAILP-NIL
Version 5, 9-Dec-88, Released 12-Dec-88
Synopsis: Operation of TAILP given NIL
Status: passed, Jan 89 X3J13
+ TEST-NOT-IF-NOT
Version 3, 1 Dec 88, Released 9 dec
Version 4, 18-Mar-89
Status: Need new version as amended.
! THE-AMBIGUITY
Version 2, 11-Jan-89, Released 11-Jan-89
Comments: typo, sense wrong
Status: tabled, vote on 2
! TIME-ZONE-NON-INTEGER
Version 1, 13-Mar-89, Released 16-Mar-89
Status: ready for vote
+* TYPE-OF-UNDERCONSTRAINED
Version 3, 12-Dec-88, Released 12 Dec 88
Comments: Accepted, with amendments
Version 5, 16-Mar-89
Comments: constraints wrong
Status: ** NEED NEW VERSION ***
! UNDEFINED-VARIABLES-AND-FUNCTIONS
Synopsis: What happens on an undefined function call, unbound variable ref?
Version 1, 29-Nov-88, Released 11-Jan-89
Comments: Lumping SLOT-UNBOUND in with unbound special variables was a mistake,
as SLOT-UNBOUND is an extension mechanism, not only a safety checking
mechanism. Also there were some wording problems. Gabriel and Gregor
are to submit a revised proposal.
No version arrived.
Status: vote on 1?
+ UNREAD-CHAR-AFTER-PEEK-CHAR
Version 2, 2-Dec-88, Released 12-Dec-88
Status: passed, Jan 89 X3J13
+ VARIABLE-LIST-ASYMMETRY
Version 3, 08-Oct-88, Released 9 Dec 88
Status: passed, Jan 89 X3J13
+ WITH-OUTPUT-TO-STRING-APPEND-STYLE
Version 5, 7-JUN-88
Status: Passed, 1988?
∂20-Mar-89 0002 X3J13-mailer X3J13 mailer
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 20 Mar 89 00:02:29 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa07578; 20 Mar 89 2:47 EST
Received: from utokyo-relay by RELAY.CS.NET id ai28052; 20 Mar 89 2:38 EST
Received: by ccut.cc.u-tokyo.junet (5.51/6.3Junet-1.0/CSNET-JUNET)
id AA05005; Mon, 20 Mar 89 14:16:29 JST
Received: from kepa.cc.aoyama.junet by aoyama.cc.aoyama.junet (4.0/6.4J.BETA2-agu2)
id AA08005; Mon, 20 Mar 89 13:59:10 JST
Received: by kepa.cc.aoyama.junet (4.0/6.3Junet-1.0)
id AA00673; Mon, 20 Mar 89 13:59:37 JST
Date: Mon, 20 Mar 89 13:59:37 JST
From: Masayuki Ida <ida%cc.aoyama.junet@UTOKYO-RELAY.CSNET>
Return-Path: <ida@cc.aoyama.junet>
Message-Id: <8903200459.AA00673@kepa.cc.aoyama.junet>
To: x3j13@SAIL.STANFORD.EDU
Cc: ida%cc.aoyama.junet@UTOKYO-RELAY.CSNET
Subject: X3J13 mailer
I finally found that I did NOT receive ANY X3J13 mails
since March 6 or 7 until today.
I believe something was wrong with the mailer at stanford or
at the japanese gate way.
Editorial mailer, and other mailers are OK.
Anyway, I will attend the Fairfax meeting as a member,
though I have not get any fresh information for two weeks.
Looking forward to seeing you all at Fairfax.
Masayuki Ida
∂20-Mar-89 1229 X3J13-mailer Re: Fatal vesus Harmless
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 20 Mar 89 12:29:29 PST
Received: from snail.Sun.COM (snail.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.0)
id AA03785; Mon, 20 Mar 89 12:01:45 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.1)
id AA18569; Mon, 20 Mar 89 11:57:53 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA02722; Mon, 20 Mar 89 12:01:32 PST
Date: Mon, 20 Mar 89 12:01:32 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903202001.AA02722@clam.sun.com>
To: RPG@SAIL.Stanford.EDU, x3j13@SAIL.Stanford.EDU
Subject: Re: Fatal vesus Harmless
Cc: cl-editorial@SAIL.Stanford.EDU
Dick Gabriel's discussion of fatal versus harmless made sense
to me. I'm going to propose here that within that framework
it can make sense to PERMIT certain SPECIFIED side effects.
I still say that "unspecified by harmless" loses.
To paraphrase, a program P "has fatal consequences"
exactly if it can be preceded and followed by conforming code
so that the entire sequence including P may "crash or abnormally
terminate".
The key question remaining in my mind is what side effects
can be considered harmless. Dick mentioned a property-list-like
data structure. Let's talk about hash tables and MAPHASH.
Specifically let's talk about the result of
(let ((result (list)))
(maphash #'(lambda (key value) (push (list key value) result))
table)
result)
The order of the result of this expression is unspecified for a
given hash table at a given time, but the set of key-value pairs
is specified.
Is it OK for CONS to cause the order of this list to change? Is it
OK for CAR to cause it to change?
Since we are trying to discuss harmless side effects, suppose we wish
to allow GC to rehash, possibly changing the order. The answer must
be that CONS can change the list, because it may invoke the GC.
Since we don't specify what operations can allocate storage, it
appears that we will prefer to say that any operation at all
is permitted to change the value of the example expression above.
In either case, we have no "unspecified but harmless" side
effect of some particular Common Lisp operation. We have a
particular class of side effects that are PERMITTED
in certain circumstances. We may choose to specify that
certain classes of side effects are ALWAYS permitted.
We may say that certain side effects are permitted -- to certain
operations. Suppose we wish to permit certain Common Lisp operations
to issue progress messages, but *not* to consider progress messages as
side effects permitted for all Common Lisp operations. In
that case it appears to me that we specify that certain operations may
issue progress messages.
While agreeing with Dick Gabriel's recent note, nowhere do I see
the concept "unspecified by harmless" as useful to the definition
of Common Lisp. Some side effects may be PERMITTED. Some may even
be permitted to ALL COMMON LISP OPERATIONS. These are specified
effects, not unspecified effects, and "permitted" I think conveys
the concept much more clearly than "harmless".
∂20-Mar-89 1315 CL-Compiler-mailer issue COMPILER-VERBOSITY, version 6
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 20 Mar 89 13:15:01 PST
Received: from maths.bath.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa07991; 20 Mar 89 18:58 GMT
Received: from xenakis by mordell.maths.bath.AC.UK id aa19210;
20 Mar 89 18:59 GMT
To: masinter.pa@xerox.com
CC: cl-compiler@sail.stanford.edu, x3J13@sail.stanford.edu
In-reply-to: masinter.pa@com.xerox's message of 16 Mar 89 05:47 PST <890316-054837-3596@Xerox>
Subject: issue COMPILER-VERBOSITY, version 6
Date: Mon, 20 Mar 89 19:02:07 GMT
From: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
Sender: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
b
∂21-Mar-89 1455 X3J13-mailer Issue: COMMON-TYPE (version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89 14:55:40 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562312; Tue 21-Mar-89 17:55:26 EST
Date: Tue, 21 Mar 89 17:55 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COMMON-TYPE (version 1)
To: X3J13@SAIL.STANFORD.EDU
References: <19890320162410.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890321225520.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
This issue came up while reviewing section 2.2 of the draft standard.
Issue: COMMON-TYPE
References: CLtL p.35, p.76
Category: CHANGE
Edit history: Version 1, 20-Mar-89, by Moon
Problem description:
The type COMMON is defined in a very peculiar way and does not seem to
be useful for anything. It can be extended by users using DEFSTRUCT,
but not DEFTYPE nor DEFCLASS, but it cannot be extended by implementations.
Whether certain types such as NUMBER and ARRAY are subtypes of COMMON
is implementation-dependent. The goal of having the COMMON type was
probably to improve portability, but it is unclear how it could actually
be used in that way.
Proposal (COMMON-TYPE:REMOVE):
Remove COMMON and COMMONP from the language.
Rationale:
Keeping the definition of COMMON accurate in the new specification, in
the face of changes elsewhere in the language such as the introduction
of CLOS and the possible introduction of character registries, is
difficult when no one is sure what COMMON is for. If no one uses COMMON,
it would be less work to just get rid of it.
Current practice:
Every implementation probably implements COMMON. Moon has never seen it
used except in a program to test whether its implementation matched CLtL.
Cost to Implementors:
None.
Cost to Users:
None unless they are actually using COMMON.
Cost of non-adoption:
Implementors would have to maintain COMMON. Users would have to try to
understand it, or figure out that they didn't care about it.
Performance impact:
None.
Benefits:
Simpler language.
Esthetics:
Simpler language.
Discussion:
None.
∂21-Mar-89 1500 X3J13-mailer Issue: HASH-TABLE-SIZE (version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89 15:00:44 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562317; Tue 21-Mar-89 18:00:29 EST
Date: Tue, 21 Mar 89 18:00 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: HASH-TABLE-SIZE (version 1)
To: X3J13@SAIL.STANFORD.EDU
References: <19890320165503.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890321230023.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
This issue came up while reviewing section 2.2 of the draft standard.
Issue: HASH-TABLE-SIZE
References: CLtL p.283
Category: CLARIFICATION
Edit history: Version 1, 20-Mar-89, by Moon
Problem description:
CLtL contradicts itself on the meaning of the :SIZE argument to
MAKE-HASH-TABLE. At the top of p.283, it says that the size is "the
maximum number of entries it can hold. Usually the actual capacity of
the table is somewhat less." At the bottom of the page it says "this
argument serves as a hint to the implementation of approximately how
many entries you intend to store." So does the :SIZE intended to be the
actual capacity of the table, or the amount of storage allocated to hold
the table. For example, if the implementation of hash tables is
designed for a loading of 65%, and the user specifies :SIZE 100, does
the table returned have space allocated for 100 entries, so that it
overflows and becomes bigger when 65 entries are inserted, or does the
table have space allocated for 154 entries, so that it overflows and
becomes bigger when 100 entries are inserted?
Proposal (HASH-TABLE-SIZE:INTENDED-ENTRIES):
Believe the bottom of p.283 rather than the top. The :SIZE argument
is approximately the number of entries that can be inserted without
the table having to grow.
Rationale:
The bottom of p.283 is user-oriented, the top is implementation-oriented.
User-oriented seems more appropriate.
Current practice:
Symbolics Genera 7.4 adheres to HASH-TABLE-SIZE:INTENDED-ENTRIES.
Other implementations were not surveyed.
Cost to Implementors:
At worst adding a multiplication to MAKE-HASH-TABLE.
Cost to Users:
Probably none, but it is hard to predict.
Cost of non-adoption:
Implementations will probably vary in which of the two interpretations
they believe. The language standard will not be self-consistent.
Performance impact:
None of any significance.
Benefits/Esthetics:
More self-consistent language.
Discussion:
None.
∂21-Mar-89 1458 X3J13-mailer Issue: COMPLEX-RATIONAL-RESULT (version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89 14:58:19 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562314; Tue 21-Mar-89 17:58:03 EST
Date: Tue, 21 Mar 89 17:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COMPLEX-RATIONAL-RESULT (version 1)
To: X3J13@SAIL.STANFORD.EDU
References: <19890320164136.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890321225757.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
This issue came up while reviewing section 2.2 of the draft standard.
Issue: COMPLEX-RATIONAL-RESULT
References: CLtL p.203
Category: CLARIFICATION
Edit history: Version 1, 20-Mar-89, by Moon
Problem description:
Referring to irrational and transcendental functions, CLtL says:
When the arguments to a function in this section are all rational and
the true mathematical result is also (mathematically) rational, then
unless otherwise noted an implementation is free to return either an
accurate result of type rational or a single-precision floating-point
approximation. If the arguments are all rational but the result cannot
be expressed as a rational number, then a single-precision
floating-point approximation is always returned.
Referring to EXPT, CLtL says:
If the base-number is of type RATIONAL and the power-number is an
INTEGER, the calculation will be exact and the result will be of
type RATIONAL; otherwise a floating-point approximation may result.
What about arguments of type (complex rational)?
Proposal (COMPLEX-RATIONAL-RESULT:EXTEND):
Extend the paragraph quoted above to cover the components of complex
numbers. For (complex rational) arguments, a mathematically rational
result can be rational, (complex rational), or (complex float) at the
discretion of the implementation. For EXPT of a (complex rational) to
an integer power, the calculation must be exact and the result will
be rational or (complex rational).
Examples:
(log #c(-16 16) #c(2 2)) => 3 or approximately #c(3.0 0.0)
(expt #c(2 2) 3) => #c(-16 16)
(expt #c(2 2) 4) => -64
Rationale:
This seems most consistent with the treatment of real numbers.
Current practice:
Symbolics Genera 7.4 returns a (complex float) for the first example
and returns the specified answers for the second and third examples.
Other implementations were not surveyed.
Cost to Implementors:
Only EXPT would have to change, since the type of the other results
is at the discretion of the implementation.
Cost to Users:
Probably none, but it is hard to predict.
Cost of non-adoption:
Slightly less self-consistent language.
Performance impact:
None of any significance.
Benefits/Esthetics:
More self-consistent language.
Discussion:
None.
∂21-Mar-89 1453 X3J13-mailer Issue: PATHNAME-COMPONENT-VALUE (version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89 14:53:02 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562306; Tue 21-Mar-89 17:52:49 EST
Date: Tue, 21 Mar 89 17:52 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-COMPONENT-VALUE (version 1)
To: X3J13@SAIL.STANFORD.EDU
References: <19890320180405.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890321225242.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
This issue came up while reviewing section 2.2 of the draft standard.
Issue: PATHNAME-COMPONENT-VALUE
Related Issues:PATHNAME-CANONICAL-TYPE,
PATHNAME-SUBDIRECTORY-LIST,
PATHNAME-UNSPECIFIC-COMPONENT,
PATHNAME-WILD
References: CLtL pp.410-3
Category: CLARIFICATION and CHANGE
Edit history: Version 1, 20-Mar-89, by Moon
Problem description:
CLtL is overly restrictive on the possible values for pathname components.
These restrictions are described in a funny way that makes it unclear
whether they are requirements, guidelines, or just an example.
The restrictions are not all written down in one place, but they appear
to be as follows:
Host nil, :wild, string, or list of strings
Device nil, :wild, string, or something else ("structured")
Directory nil, :wild, string, or something else ("structured")
Name nil, :wild, string, or something else ("structured")
Type nil, :wild, or string
Version nil, :wild, :newest, positive integer, implementation
dependent symbol, or implementation-dependent integer
less than or equal to zero. Suggestions include :oldest,
:previous, :installed, 0, and -1.
PATHNAME-UNSPECIFIC-COMPONENT:NEW-TOKEN allowed implementations to
allow any component to be :UNSPECIFIC. This has been voted in.
PATHNAME-SUBDIRECTORY-LIST proposes a list of strings and keyword
symbols for the directory component.
PATHNAME-CANONICAL-TYPE proposes some new operations but does not
change the possible values of the type component.
PATHNAME-WILD proposes a portable way to test for implementation
dependent component values that indicate wildcard matching. It
does not change the possible values of any component.
Proposal (PATHNAME-COMPONENT-VALUE:SPECIFY):
The points of the proposal have been numbered to facilitate
amendments to remove or modify individual points.
When examining pathname components, conforming programs must be
prepared to encounter any of the following values:
1. Any component can be NIL, which means the component has not
been specified.
2. Any component can be :UNSPECIFIC, which means the component has
no meaning in this particular pathname.
3. Any component can be :WILD, which matches any component value.
Wild pathnames can be used with DIRECTORY but not with OPEN.
4. The host, device, directory, name, and type can be strings.
5. The host and device can be a list, a structure, or a
standard-object at the discretion of the implementation.
6. The directory can be a list of strings and symbols as detailed in
PATHNAME-SUBDIRECTORY-LIST (this assumes that it passes.)
7. The version can be any symbol or any integer. The symbol :NEWEST
refers to the largest version number that already exists in the file
system when reading, overwriting, appending, superseding, or directory
listing an existing file, and refers to the smallest version number
greater than any existing version number when creating a new file.
When constructing a pathname from components, conforming programs
must follow these rules:
11. Any component can be NIL. NIL in the host may mean a default host
rather than an actual NIL in some implementations.
12. Any component can be :WILD, which matches any component value.
Wild pathnames can be used with DIRECTORY but not with OPEN.
13. The host, device, directory, name, and type can be strings.
14. The directory can be a list of strings and symbols as detailed in
PATHNAME-SUBDIRECTORY-LIST (this assumes that it passes.)
15. The version can be :NEWEST.
16. Any component can be taken from the corresponding component
of another pathname on the same host and device.
17. An implementation might support other values for some
components, but a portable program cannot use those values.
An implementation might allow values to be transferred between
pathnames on different hosts or different devices, but a portable
program cannot rely on that.
A conforming program can use implementation-dependent values
but this can make it non-portable, for example, it might work
only with Unix file systems.
18. It is suggested, but not required, that implementations use
positive integers starting at 1 as version numbers, recognize
the symbol :oldest to designate the smallest existing version
number, and use keyword symbols for other special versions.
Consequences:
The changes relative to CLtL plus PATHNAME-UNSPECIFIC-COMPONENT
are as follows:
The definition of "structured" component is restricted to lists,
structures, and standard-objects, rather than allowing any object
whatsoever.
"Structured" hosts are allowed, a generalization of CLtL's list
of strings.
"Structured" directories are replaced by PATHNAME-SUBDIRECTORY-LIST.
"Structured" names are forbidden.
The difference between what component values a program can depend
on being able to use, versus what component values a program must
be prepared to encounter, is clarified.
Rationale:
This should make it easier to write portable programs that deal with
pathnames and make it easier for implementors by clarifying the
framework into which they must fit. Also it should make it easier
to write the Common Lisp language specification by resolving some
things that were unclear about the status quo.
Adding "structured" hosts conforms to current practice.
Substituting a default host for NIL conforms to current practice
in implementations that require all pathnames to have a specific host.
Removing "structured" names should improve portability without causing
any harm, assuming no implementation uses structured names. This will
improve portability by allowing programs to do string manipulation on
names, although such programs still have to be careful since the valid
characters and maximum length of a name are implementation-dependent.
Disallowing transferral of nonstandard component values between
different hosts or different devices allows implementations to support
multiple incompatible file systems.
Current practice:
All versions of Symbolics Genera violate CLtL in the matter of hosts,
since it uses standard-objects as the host component. Genera deviates
slightly from PATHNAME-SUBDIRECTORY-LIST, but otherwise conforms to
PATHNAME-COMPONENT-VALUE:SPECIFY.
Other implementations were not surveyed.
This proposal assumes that no current or planned implementation
uses structured names, not even for wildcards.
Cost to Implementors:
Most implementations already conform, except for the changes required
by PATHNAME-UNSPECIFIC-COMPONENT and PATHNAME-SUBDIRECTORY-LIST, so
the cost of this proposal itself should be minimal. It is conceivable
that an implementation may exist that has to change its pathname
representation, for example one that uses numbers as structured devices.
Cost to Users:
None.
Cost of non-adoption:
Pathnames will continue to be a poorly specified part of the language.
Performance impact:
None of any significance.
Benefits/Esthetics:
The boundary between the specified behavior of pathnames and the
implementation-dependent behavior of pathnames will be more clear.
Discussion:
A possible alternative to item 16 that's worth considering is:
16. Any component can be taken from the corresponding component
of another pathname. When the two pathnames are for incompatible
file systems (in implementations that support multiple file
systems), an appropriate translation occurs. If no meaningful
translation is possible, an error is signalled. The definition
of "appropriate" and "meaningful" is implementation-dependent.
This provides more useful behavior that conforming programs can
depend upon, but the behavior cannot be as precisely specified.
A significant amount of the Symbolics Genera pathname facility is
related to this capability, and it's used a lot in heterogeneous
networks, so maybe this is a useful capability that ought to be
called for in the language. The cost to implementors is small since
they could define "appropriate" and "meaningful" to be whatever is
easiest for them, if their users don't complain.
∂21-Mar-89 1629 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89 16:29:22 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562415; Tue 21-Mar-89 19:29:06 EST
Date: Tue, 21 Mar 89 19:28 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
To: X3J13@SAIL.STANFORD.EDU
References: <19890317213333.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890322002858.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
This version is edited to clarify that the semantics of simple-array
are not being changed, and supersedes version 8 which you already saw.
Issue: ADJUST-ARRAY-NOT-ADJUSTABLE
References: ADJUST-ARRAY (p297), ADJUSTABLE-ARRAY-P (p293),
MAKE-ARRAY (pp286-289), simple arrays (p28, 289)
Category: CLARIFICATION
Edit history: 22-Apr-87, Version 1 by Pitman
15-Nov-88, Versions 2a,2b,2c by Pitman
02-Dec-88, Version 3 by Pitman
11-Jan-89, Version 4 by Pitman
16-Jan-89, Version 5, by Gabriel. Amended at the meeting to shorten.
23-Jan-89, Version 6, by Moon. Shorten without the bug introduced
by the amendment, add clarification of SIMPLE-ARRAY type.
15-Feb-89, Version 7, by Pitman. Minor changes per comments from
RPG and Dalton.
11-Mar-89, Version 8, by Pitman. Change category, add endorsements.
17-Mar-89, Version 9, by Moon, fix wording and examples to make it
clear that the semantics of simple-array is unchanged.
Problem Description:
The description of the :ADJUSTABLE option to MAKE-ARRAY on p288
says that ``the argument, if specified and not NIL, indicates that
it must be possible to alter the array's size dynamically after
it is created. This argument defaults to NIL.''
The description of the :ADJUSTABLE option does not say what
MAKE-ARRAY will do if the argument is unsupplied or explicitly NIL.
The description of ADJUSTABLE-ARRAY-P on p293 says that it is
true ``if the argument (which must be an array) is adjustable, and
otherwise false.'' However, the description of MAKE-ARRAY makes
it clear that this is not necessarily the same as asking if
the array was created with :ADJUSTABLE T. If ADJUSTABLE-ARRAY-P
returns NIL, you know that :ADJUSTABLE NIL was supplied (or no
:ADJUSTABLE option was supplied), but if ADJUSTABLE-ARRAY-P returns
T, then there is no information about whether :ADJUSTABLE was used.
The description of ADJUST-ARRAY on pp297-298 says that it is
``not permitted to call ADJUST-ARRAY on an array that was not
created with the :ADJUSTABLE option.'' This is inconsistent with
ADJUSTABLE-ARRAY-P.
A problem which comes up in practice is that some programmers
expect runtime error checking if they have done
(MAKE-ARRAY ... :ADJUSTABLE NIL) and they later try to adjust
the array using ADJUST-ARRAY.
The definition of the SIMPLE-ARRAY type and its subtypes needs
clarification of its relationship to adjustability.
Proposal (ADJUST-ARRAY-NOT-ADJUSTABLE:CLARIFY):
1. ADJUSTABLE-ARRAY-P is true of all arrays created with a true
:ADJUSTABLE option to MAKE-ARRAY. Whether ADJUSTABLE-ARRAY-P is
true of some other arrays is unspecified.
2. If MAKE-ARRAY is called with the :ADJUSTABLE, :FILL-POINTER,
and :DISPLACED-TO arguments each either unspecified or false, the
resulting array is a simple array. (This just repeats what CLtL
says on page 289, it's here to aid in understanding the next point.)
3. If MAKE-ARRAY is called with one or more of the :ADJUSTABLE,
:FILL-POINTER, or :DISPLACED-TO arguments true, whether the
resulting array is simple is unspecified.
4. ADJUST-ARRAY ``should signal'' an error if ADJUSTABLE-ARRAY-P
of its first argument is false. ADJUST-ARRAY must not signal an
`array not adjustable' error if ADJUSTABLE-ARRAY-P of its first
argument is true.
5. The value of ADJUSTABLE-ARRAY-P on a simple array is unspecified.
Note: ``should signal'' is taken from the new error terminology.
It means that in ``safe code'' (code compiled with highest safety)
an error must be signalled, but that in unsafe code (code not compiled
with highest safety), an error might or might not be signalled.
Clarifications and Logical Consequences:
a. Whether an array can be both simple and adjustable is unspecified.
b. There is no specified way to create an array for which ADJUSTABLE-ARRAY-P
definitely returns NIL.
c. There is no specified way to create an array that is non-simple.
d. This legitimizes ADJUSTABLE-ARRAY-P as an appropriate predicate to
determine whether ADJUST-ARRAY will reliably succeed.
e. If ADJUST-ARRAY is invoked on an array that was created without
supplying :ADJUSTABLE true, an `array not adjustable' error
``should be signalled'' unless ADJUSTABLE-ARRAY-P returns true on
that array (in which case it must not signal an `array not adjustable'
error).
f. There is no change to the meaning of the type SIMPLE-ARRAY, only
a clarification that a conforming program cannot assume that any
array is not simple.
Rationale:
This effectively makes the status quo explicit. This preserves the
raison d'etre of simple arrays, which is to provide a portable interface
to implementation-dependent specialized arrays that trade decreased
functionality for faster access.
A proposed alternative was to specify a way to create an array that is
guaranteed not to be simple. This would have required large changes
to some implementations and would be of little benefit to users.
Users need to know that certain arrays are simple, so they can put in
declarations and get higher performance, but users have no need to be
able to create arrays that are definitely non-simple (for lower
performance) or definitely non-adjustable (to cause errors).
Examples:
1. The following program is conforming. It is unspecified which branch
of the IF it follows.
(defun double (a)
(if (adjustable-array-p a)
(adjust-array a (* (length a) 2))
(let ((new (make-array (* (length a) 2))))
(replace new a :end1 (length a))
new)))
(double (make-array 30))
2. The following program is conforming. In no implementation is the
type declaration violated.
(let ((a (make-array 100)))
(declare (simple-array a))
(frob a))
3. The following program is non-conforming. The consequences of this
program are undefined because the type declaration is violated in some
valid implementations.
(let ((a (make-array 100 :adjustable t)))
(declare (simple-array a))
(frob a))
Current Practice:
Probably everyone is compatible with this proposal.
Symbolics Genera makes :ADJUSTABLE NIL arrays adjustable in most cases,
and ignores adjustability in deciding whether an array is simple,
and is compatible with this proposal.
Lucid, IIM, and Symbolics Cloe make :ADJUSTABLE NIL arrays non-adjustable
in all cases, and make all arrays non-simple unless the Common Lisp
language requires them to be simple, and are compatible with this proposal.
Cost to Implementors:
It's in principle possible that some implementation would have to change,
but in practice there are no known implementations that would have to change.
Cost to Users:
None. This is a fully compatible change from the user's standpoint.
Benefits:
Users would know what to expect.
Non-Benefits:
Users who expect adjusting arrays created with :ADJUSTABLE NIL to signal
an error would not get the desired error checking.
Aesthetics:
Most people believe the status quo is unaesthetic. Having an aspect of
the language explicitly unspecified is more aesthetic than having it
implicitly unspecified on account of vague or inconsistent documentation.
Discussion:
Pitman, Moon, Gabriel, and Steele support this amended proposal.
MACSYMA ran into portability problems due to the status quo.
If the issue had been documented, that would have helped.
Encouraging implementations that are able to at least make
(MAKE-ARRAY ... :ADJUSTABLE NIL) create non-adjustable arrays
where possible would help, too.
We considered proposals to incompatibly change this primitive in a
variety of ways, but the community was very split with strong proponents
and opponents of each alternate proposal.
The overriding concern driving this proposal is that Symbolics
has asserted that most of the other really interesting proposals would
likely involve a sizable cost to implementors (and their installed bases)
to implement what were judged by some as gratuitous changes from the
status quo.
Pitman wishes some of the other proposals were economically feasible to
pursue but reluctantly agrees that maintaining (and clearly documenting)
the status quo is probably the most reasonable avenue left to us.
∂21-Mar-89 1732 CL-Compiler-mailer **DRAFT** issue CLOS-MACRO-COMPILATION, version 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89 17:32:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562475; Tue 21-Mar-89 20:32:29 EST
Date: Tue, 21 Mar 89 20:32 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue CLOS-MACRO-COMPILATION, version 2
To: cl-compiler@SAIL.STANFORD.EDU
cc: x3j13@SAIL.STANFORD.EDU
In-Reply-To: <8903132248.AA02496@defun.utah.edu>
Message-ID: <19890322013216.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
I would go with MINIMAL for now. It leaves a lot of behavior
unspecified, and we can fill in that behavior later when we
add metaobjects to the standard.
Relatively small comments:
The compiler should be allowed to warn, but not error, about
failures of lambda-list congruence between methods or generic
functions in the file being compiled and methods or generic
functions in the Lisp doing the compilation. When you say
the compiler may not "perform tests" between these, it's not
clear whether you mean to rule out only errors or both errors
and warnings.
The only thing here that might be overspecification is allowing a
DEFINE-METHOD-COMBINATION to be used later in the same compilation.
However, I see no real harm in that, and it would often be
convenient for programmers, so leave it. But if someone else
moves to remove it, I will not object.
Evaluation of the form in EQL parameter specializer names in DEFMETHOD
needs to be covered. I think this is tied up with the pending compiler
committee issue DEFCONSTANT-VALUE (whose version 2 writeup I don't like,
it's too messy). The choices seem to be to require the form in an EQL
parameter specializer name to be evaluable at compile time, to require
it to depend only on constants defined in the file being compiled, or to
permit its evaluation to be deferred until load time. I don't like the
first choice. I think for both DEFCONSTANT and EQL the semantics should
be as if it were never evaluated until load time, with the compiler
allowed to evaluate it sooner only if it can prove that that does not
change the semantics. I'd be happier if the mechanism the compiler
uses to do this tentative evaluation were made available to the user,
but that can be deferred until metaobjects.
∂21-Mar-89 2048 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 21 Mar 89 20:48:46 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01278g; Tue, 21 Mar 89 20:43:21 PST
Received: by challenger id AA22664g; Tue, 21 Mar 89 20:38:38 PST
Date: Tue, 21 Mar 89 20:38:38 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903220438.AA22664@challenger>
To: x3j13@sail.stanford.edu
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
People have continued to debate this issue. Part of the confusion is
what CLtL really says about simple arrays and adjustability. The
cause of the confusion is that various people have advanced difficult
to understand arguments and proposals (myself included).
As mentioned in the statement of ADJUST-ARRAY-NOT-ADJUSTABLE (Version
9), I agreed to support it, and I also agreed that it was a
clarification and not a change,
Because I had become confused by the issue, I decided to go back to
CLtL to find the consistent readings of the passages on simple arrays
and adjustability. As part of this exercise I tried to write up an
analysis of the possible interpretations of the the statements in
question. I often use this hermeneutical act to understand difficult
issues.
The result is that I think there are exactly two plausible consistent
readings, with one much more plausible than the other. Both readings
are inconsistent with ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9).
Therefore, I conclude that ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9) is
a change, not a clarification, and I must withdraw my agreement that
it is a clarification.
Whether we wish to adopt it is another question, to which I offer no
specific comment or suggestion. I am convinced that if some people
have read CLtL as meaning what ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
states and implemented simple arrays that way, we are in quite a bind.
The only minor comment I have is a general one: We should be wary of
changes (rather than clarifications) at this stage of standardization.
This message is very long and contains lots of close reasoning and
boring details. By its length and detail some might read it as a
strong criticism of the authors of ADJUST-ARRAY-NOT-ADJUSTABLE
(Version 9) - it really isn't (in fact, before I this exercise I
believed that the contents of ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
would be one of the plausible interpretations). It is simply what I
found and how I found it.
If you want to get to the heart of the matter, ask your text editor to
search for <<yoo-hoo>> and start reading there.
*************************
* Start of the Analysis *
*************************
In this message I will use the notation (S-i) to name statements;
(S-8) is to be read as ``statement 8.'' I will use (I-i-j) to name
interpretations of statments; (I-8-2) is to be read as ``the second
interpretation of statement 8.'' (I-7;8-4) is to be read as ``the
fourth interpretation of the statements 7 and 8 taken together.'' I
will use (*I-i-j) to name incorrect interpretations of statements;
(*I-8-2) is to be read as ``the (incorrect) second interpretation of
statement 8.'' I will use (C-i[J1,...,Jn) to name conclusions derived
from statements; (C-2[S-1,I-8-2]) is to be read as ``conclusion 2
derived from statement 1 and the second interpretation of statement
8.''
There are several relevant statements in CLtL.
(S-1) [from Page 28] An array that is not displaced to another array,
has no fill pointer, and is not to have its size adjusted dynamically
after creation is called a simple array.
(S-2) [from Page 288] :ADJUSTABLE: This argument, if specified and not
NIL, indicates that it must be possible to alter the array's size
dynamically after it is created.
(S-3) [immediately follows (S-2)] This argument defaults to NIL.
(S-4) [from Page 289] If MAKE-ARRAY is called with the :ADJUSTABLE,
:FILL-POINTER, and :DISPLACED-TO arguments each either unspecified or
false, the resulting array is a simple array.
(S-5) [from Page 293] This predicate [ADJUSTABLE-ARRAY-P] is true if
the argument (which must be an array) is adjustable, and otherwise
false.
(S-6) [from Page 297] It is not permitted to call ADJUST-ARRAY on an
array that was not created with the :ADJUSTABLE option.
(S-7) [immediately follows (S-6)] The predicate ADJUSTABLE-ARRAY-P may
be used to determine whether or not an array is adjustable.
First, let's look at the various interpretations of these statements.
***************************
* Interpretation of (S-1) *
***************************
The statement (S-1) appears to be in the form of a definition.
However, the phrase ``is called'' could be taken as a non-standard way
to introduce a definition and might instead be taken as a conditional
statement: Schematically, ``X's are called Y's'' could be taken to
mean ``If something is an X, then it is a Y.''
I don't think this is a plausible reading in a programming language
specification. Consider this sentence:
``A number that is divisible by 9 is called a well-tempered number.''
I think this is a fair definition. Certainly we would say that, by
this definition, the number 11 is not a well-tempered number.
Nevertheless, a possible interpretation of (S-1) could be:
(*I-1-1) If an array is not displaced to another array, has no fill
pointer, and is not to have its size adjusted dynamically after
creation, it is a simple array (and there may be simple arrays that do
not satisfy these properties).
However, if we look at the other statements in Chapters 2 and 17 we
see the use of ``is called'' throughout in what appears to be a
definitional sense. If (S-1) lacks definitional force, then so do
these statements:
Page 29: One-dimensional arrays are called vectors in Common Lisp
and constitute the type VECTOR (which is therefore a subtype
of ARRAY).
Page 29: All implementations provide specialized arrays for the cases
when the components are characters (or rather, a special subset of the
characters); the one-dimensional instances of this specialization are
called strings.
Page 29: All implementations are also required to provide specialized
arrays of bits, that is, arrays of type (ARRAY BIT); the
one-dimensional instances of this specialization are called bit
vectors.
Page 286: One-dimensional arrays are called vectors.
Page 286: Vectors whose elements are restricted to type STRING-CHAR
are called strings.
Page 286: Vectors whose elements are restricted to type BIT are called
bit-vectors.
Nothing but one-dimensional arrays are called or considered vectors,
and so I think ``is called'' can reasonably be interpreted only as
definitional.
I believe (*I-1-1) is not reasonable by the two arguments of incorrect
form for a conditional and the use of the ``is called'' form in
definitional senses elsewhere in Chapter 2.
I believe the definitional interpretation of (S-1) is this:
(I-1-1.5) Definition: An array is called a simple array if and only if
the array is not displaced to another array, has no fill pointer, and
is not to have its size adjusted dynamically after creation.
Further, I think the obvious meaning of (S-1) is this:
(I-1-2) Definition: An array is called a simple array if and only if
the array is not displaced to another array, has no fill pointer, and
cannot have its size adjusted dynamically after creation.
Another interpretation of (S-1) is possible. Note that the that the
phrase ``is not to have its size adjusted dynamically after creation''
is used rather than the less equivocal ``cannot have its size adjusted
dynamically after creation.'' One way to understand this phrasing is
as a stylistic device to produce the relatively uniform pattern ``an
array that is, ..., has, ... and is...'' rather than the relatively
non-uniform pattern ``an array that is, ..., has, ... and can....'' I
believe that this stylistic nuance is what Steele had in mind, but an
alternative is possible.
The alternative is derived as follows: If something ``is not to be''
acted upon in some particular way, then it is not the *intention* of
the actor to act upon that thing in that way. Therefore, we have the
alternative interpretation:
(I-1-3) Definition: An array is called a simple array if and only if
the array is not displaced to another array, has no fill pointer, and
is not intended to have its size adjusted dynamically after creation.
This results in a curious meaning for ``simple array.'' A simple array
is a legitimate type (SIMPLE-ARRAY appears on Page 34 in the sentence,
``SIMPLE-ARRAY is a subtype of ARRAY.'' It also appears on page 43 as
one the Common Lisp Standard Type Specifiers, and on Page 42 it
states, ``in Common Lisp, types are named by Lisp objects,
specifically symbols and lists, called type specifiers.''), and so it
must be possible to make such an array and to test objects for this
type. If (typep A 'simple-array) is true, then A is an array that,
among other things, was *intended* to not have its size altered
dynamically after creation.
There is another interpretation of (S-1), which interprets ``is not
to have'' as ``doesn't happen to have.''
(*I-1-4) An array that is not displaced to another array, has no fill
pointer, and doesn't happen to have its size adjusted dynamically
after creation is called a simple array.
I think this is an unlikely interpretation because it is clear that a
simple array can be created, and at the point of creation MAKE-ARRAY
would not know whether the size will happen to be adjusted later.
There is yet another interpretation of (S-1), but it cannot be presented
easily until after some other arguments have been made.
***************************
* Interpretation of (S-2) *
***************************
The statement (S-2) states that the argument :ADJUSTABLE can be used
to create an array whose size can be altered dynamically after
creation.
If (I-1-2) is the correct interpretation, then supplying a non-NIL
:ADJUSTABLE argument results in an array whose size *can* be altered
dynamically after creation, and so an array made this way is not a
simple array.
If (I-1-3) is the correct interpretation, then supplying a non-NIL
:ADJUSTABLE argument results in an array that is *intended* to have
its size altered dynamically after creation, and so an array made this
way is not a simple array.
(C-1[I-1-2,I-1-3,S-2]) Supplying a non-NIL :ADJUSTABLE argument to
MAKE-ARRAY results in a non-simple array. The basis for this
conclusion is the definitional nature of (S-1) regardless of the two
variants of the definition.
In fact, if we look at the statements regarding :FILL-POINTER and
:DISPLACED-TO, we see that if either of them is supplied and true, the
resulting array is also not simple (using the same argument used for
:ADJUSTABLE).
Therefore,
(C-2[I-1-2,I-1-3]) An array created with any one of :ADJUSTABLE,
:FILL-POINTER, and :DISPLACED-TO specified and non-NIL is not simple.
***************************
* Interpretation of (S-3) *
***************************
The statement (S-3) has a single interpretation.
***************************
* Interpretation of (S-4) *
***************************
The statement (S-4) states that if all three of the :ADJUSTABLE,
:FILL-POINTER, and :DISPLACED-TO arguments are unspecified or false, a
simple array is produced.
Combining this with (C-2) we get:
(C-3[S-4,C-2]) An array created with any one of :ADJUSTABLE,
:FILL-POINTER, and :DISPLACED-TO specified and non-NIL is not simple.
The force of (S-2) and (S-4) is that only a part of the type structure
of arrays is specified. There is definitely a way to create a simple
array, and definitely ways to create non-simple arrays, but whether
non-simple arrays are further distinguished based on the arguments
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO is not specified.
***************************
* Interpretation of (S-5) *
***************************
We will return to statement (S-5) later. Its interpretation is clear,
but which arrays are adjustable is not.
***************************
* Interpretation of (S-6) *
***************************
Statement (S-6) is quite tricky.
The problem is with the phrase ``is not permitted''; the question is
whether it is synonymous with ``is an error'' or whether it is
stronger.
The case for ``is not permitted"" being stronger than ``is an error''
is very compelling, I feel. First, taken as an English phrase, it is
strong: If you are not permitted to call ADJUST-ARRAY, then you do not
have permission to call it; in other words, you are not allowed to
call it, calling it is not tolerated, consent was not given to call
it, you do not have license to call it, you are not authorized to call
it, you do not have the opportunity to call it, it is not possible to
call it.
Second, ``is not permitted'' is not listed on Page 6 as one of the
phrases synonymous with ``is an error.'' If Steele wanted to actually
prohibit something, he would not be able to use the relatively
intuitive ``must not'' since that means ``is an error,'' which can be
taken to mean ``is allowed.'' That is, within the linguistic bounds of
CLtL it is possible to interpret the statement ``you must not do X''
as ``you are allowed to do X.''
The phrase ``is not permitted'' is used elsewhere in CLtL. The most
directly informative usage is on Page 72:
``The names NIL and T are constants in Common Lisp. Although they are
symbols like any other symbols, and appear to be treated as variables
when evaluated, it is not permitted to modify their values. See
DEFCONSTANT.''
Changing the values of NIL and T is a pretty serious offense. Steele
could have directly used the wording ``is an error,'' but he chose a
phrase not formally defined. He also could have said that NIL and T
are constants exactly like those defined by DEFCONSTANT, but he chose
informal wording that is stronger than ``is an error.'' Finally, the
advice to see DEFCONSTANT is given, almost as an afterthought.
Here is the main interpretation of (S-6):
(I-6-1) Calling ADJUST-ARRAY on an array that was not created with the
:ADJUSTABLE option is prohibited.
An array is ``adjustable'' if it is capable of being adjusted.
ADJUST-ARRAY is the only function in Common Lisp that can adjust an
array. Therefore, if ``calling ADJUST-ARRAY...is prohibited'' in some
situation, then that array is not adjustable in that situation. The
situation pointed out by (I-6-1) is that the ``array ... was not
created with the :ADJUSTABLE option.''
Combining this with (S-2) we get:
(C-4[I-6-1,S-2]) An array is adjustable if and only if the array was
created with the :ADJUSTABLE option.
Now let's look at the case for (S-6) being permissive.
The remark ``see DEFCONSTANT'' could be taken to mean that NIL and T
are simply constants and are to be treated that way, no more, no less.
Under DEFCONSTANT it states that altering the value of a constant ``is
an error.''
So here is the alternative:
(I-6-2) Calling ADJUST-ARRAY on an array that was not created with the
:ADJUSTABLE option is an error (that is, it is allowed).
***************************
* Interpretation of (S-7) *
***************************
On the face of it, (S-7) is a restatement of (S-5). The two
alternative readings result from either taking its presence as
relevant or irrelevant. That is, one can either believe that (S-7)
conveys some new information by its location relative to other
statements or that the reading of CLtL is as if (S-7) were deleted
I believe that essentially deleting (S-7) is not reasonable, mostly
because Steele is a better writer than that interpretation would
imply.
The fact that (S-7) immediately follows (S-6) implies that there is
some relation between them. In a two-sentence paragraph it is odd to
have the second sentence add no information to the first. The obvious
relation is that ADJUSTABLE-ARRAY-P is the predicate that can be used
to determine whether it is permitted to call ADJUST-ARRAY.
(I-7-1) ADJUSTABLE-ARRAY-P can be used to determine whether or not
ADJUST-ARRAY is permitted.
Consider (I-6-1). Using (C-4), since ADJUST-ARRAY can be called on
exactly those arrays that were created with the :ADJUSTABLE option,
and since ADJUSTABLE-ARRAY-P can be used to determine whether
ADJUST-ARRAY can be used, we get:
(C-5[C-4,S-5]) ADJUSTABLE-ARRAY-P can be used to determine whether or
not an array was created with the :ADJUSTABLE option.
Given this, following (S-6) with (S-7) is natural, because it serves
to reinforce the interpretation (I-6-1) because ADJUSTABLE-ARRAY-P
talks about adjustability.
Let's put (I-6-1), (I-7-1), and (C-5) together:
(I-6;7-1) ADJUST-ARRAY can be called only on adjustable arrays, that
is, only on arrays created with the :ADJUSTABLE option.
ADJUSTABLE-ARRAY-P can be used to determine whether an array was
created with the :ADJUSTABLE option.
Consider (I-6-2). The effect of (I-7-1) is to reinforce the
interpretation (I-6-2), because (S-7) states that ADJUSTABLE-ARRAY-P
must be used to determine adjustability, not the use of the
:ADJUSTABLE argument in MAKE-ARRAY.
We can rephrase (I-6-2) and (I-7-1) as follows:
(I-6;7-2) Calling ADJUST-ARRAY on an array that was not created with
the :ADJUSTABLE option is an error (that is, it is allowed); and
ADJUSTABLE-ARRAY-P can be used to determine whether or not it is
allowed.
**************************
* Interpretation of CLtL *
**************************
Now let's look at (I-1-2) and (I-1-3).
(I-1-2) can be taken either under (I-6;7-1) or under (I-6;7-2).
Under (I-6;7-1) and recalling (C-2), (C-3), and (C-4) we get:
Position 1: The only simple arrays are those created with the
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO arguments each either
unspecified or false. All simple arrays are not adjustable. An array
is adjustable if and only if it was created with the :ADJUSTABLE
option. ADJUSTABLE-ARRAY-P is false of all simple arrays.
There is an affinity between (I-1-2) and (I-6;7-1) because the
:ADJUSTABLE argument states whether it is possible to adjust the
array.
Under (I-6;7-2) and recalling (C-2) and (S-5), we get:
Position 2: The only simple arrays are those created with the
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO arguments each either
unspecified or false. A simple array may or may not be adjustable. An
array created with the :ADJUSTABLE option unspecified or NIL might be
adjustable. ADJUSTABLE-ARRAY-P can be used to determine whether an
array is adjustable.
This is weak because (I-1-2), (S-2), and (S-4) taken together implies
that the :ADJUSTABLE argument controls adjustability. (I-6-2) implies
that :ADJUSTABLE unspecified or NIL might result in an adjustable
array.
(I-1-3) must be considered under both (I-6;7-1) and (I-6;7-2).
Looking at (I-1-3) with (I-6;7-1), we get Position 1 again, because the
:ADJUSTABLE arguments signals intent to adjust an array. Here,
(I-6;7-1) implies that one cannot call ADJUST-ARRAY on an array that
was not intended to be adjusted. I feel this is a weak pair of
interpretations.
Looking at (I-1-3) with (I-6;7-2), we get Position 2 again. Here it is
allowed to call ADJUST-ARRAY on an array that wasn't intended to be
adjusted. There is some affinity between (I-1-3) and (I-6;7-2) because
the :ADJUSTABLE argument signals intention only. The only intention
that is required to be acted upon is specifying a non-NIL :ADJUSTABLE
argument, which must result in an adjustable array. If your intention
is to not adjust the array, you should not care whether it is actually
adjustable. Therefore, (I-6-2) is a sensibly paired with (I-1-3).
The variations of ``can not be adjusted'' and ``not intended to be
adjusted'' have little differential effect on the final
interpretations except insofar as Position 1 is stronger when paired
with (I-1-2) and Position 2 is stronger with (I-1-3). I believe that
the strength of the argument regarding ``is not permitted'' coupled
with the weakness the plausibility of a type being defined with
respect to intention combine to make Position 1 the stronger
interpretation.
*************************************
* Interpretation of (S-1) Revisited *
*************************************
Given the clearly definitional nature of (S-1), let's look at the
question of whether there is any basis in CLtL for an array created
with one of :ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO specified
and non-NIL to be simple.
The reasoning for such a situation is as follows: Under Position 2 it
is possible for a simple array to be adjustable. The expression
(MAKE-ARRAY n :ADJUSTABLE NIL) creates a simple array under Position
2, and so why shouldn't (MAKE-ARRAY n :ADJUSTABLE T), since MAKE-ARRAY
probably ignores the :ADJUSTABLE argument.
For this to be allowed, (S-1) must be a partial or conditional
definition. That is, (S-1) might be definitional, but only for
certain implementations, or part of the definition might apply only
for certain implementations. The remainder of the paragraph that
starts with (S-1) continues as follows:
(S-8) The user may provide declarations that certain arrays will be
simple.
(S-9) Some implementations can handle simple arrays in an especially
efficient manner; for example, simple arrays may have a more compact
representation than non-simple arrays.
(S-8) and (S-9) clearly imply that the reason for simple arrays is
efficiency. (S-8) talks about declarations provided by the user. When
a Common Lisp programmer provides a declaration that does not have
semantic import, this can signal only intention. Therefore, the
interpretation (I-1-3) would seem to make sense.
I believe that nothing in (S-8) and (S-9) alters the definitional
nature of (S-2). The most (S-8) and (S-9) could do is limit its
applicability of the definition. That is, neither (S-8) nor (S-9)
imply that (S-1) is not a definition, but they could modify the
conditions that the definition predicates.
The paragraph starting with (S-1) could be taken as a description of a
type that is useful only in implementations that act differently
according to the user's intentions as signaled by declarations. Since
(S-4) requires that some arrays be simple, implementations that have
no use for simple arrays are forced to have them.
Another interpretation of (S-1) is then:
(*I-1-5) An array that is not displaced, has no fill pointer, and has
been created with the intention not to have its size altered
dynamically after creation in an implementation that honors
declarations is a simple array.
I think this is a far-fetched reading, particularly since Steele
is capable of stating something like this much more precisely than
with the series (S-1), (S-8), and (S-9).
***********************
* End of the Analysis *
***********************
<<yoo-hoo>>
For those of you who could not stand to read the hermeneutic
arguments, here are the only two consistent readings of CLtL regarding
simple arrays and adjustability. I believe that Position 1 has the
stronger set of arguments behind it and is, I believe, the preferred
reading:
Position 1: The only simple arrays are those created with the
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO arguments each either
unspecified or false. All simple arrays are not adjustable. An array
is adjustable if and only if it was created with the :ADJUSTABLE
option. ADJUSTABLE-ARRAY-P is false of all simple arrays.
Position 2: The only simple arrays are those created with the
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO arguments each either
unspecified or false. A simple array may or may not be adjustable. An
array created with the :ADJUSTABLE option unspecified or NIL might be
adjustable. ADJUSTABLE-ARRAY-P can be used to determine whether an
array is adjustable.
Here are the points of ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9). I will
note whether each point is consistent with each of the two Positions
so that Version 9 can be seen to be a change rather than a
clarification:
1. ADJUSTABLE-ARRAY-P is true of all arrays created with a true
:ADJUSTABLE option to MAKE-ARRAY. Whether ADJUSTABLE-ARRAY-P is
true of some other arrays is unspecified.
This weakly contradicts Position 1, since Position 1 states which
arrays are adjustable and which aren't. It is consistent with
Position 2.
2. If MAKE-ARRAY is called with the :ADJUSTABLE, :FILL-POINTER,
and :DISPLACED-TO arguments each either unspecified or false, the
resulting array is a simple array. (This just repeats what CLtL
says on page 289, it's here to aid in understanding the next point.)
This is simply (S-4).
3. If MAKE-ARRAY is called with one or more of the :ADJUSTABLE,
:FILL-POINTER, or :DISPLACED-TO arguments true, whether the
resulting array is simple is unspecified.
This contradicts both Position 1 and Position 2.
4. ADJUST-ARRAY ``should signal'' an error if ADJUSTABLE-ARRAY-P
of its first argument is false. ADJUST-ARRAY must not signal an
`array not adjustable' error if ADJUSTABLE-ARRAY-P of its first
argument is true.
This is consistent with both Position 1 and Position 2.
5. The value of ADJUSTABLE-ARRAY-P on a simple array is unspecified.
This contradicts Position 1 and is consistent with Position 2.
Let's also look at the ``Clarifications and Logical Consequences''
presented in the proposal:
a. Whether an array can be both simple and adjustable is unspecified.
This contradicts Position 1 and is consistent with Position 2.
b. There is no specified way to create an array for which ADJUSTABLE-ARRAY-P
definitely returns NIL.
This contradicts Position 1 and is consistent with Position 2.
c. There is no specified way to create an array that is non-simple.
This contradicts both Position 1 and Position 2. In fact, this
contradicts (S-1) under any reasonable interpretation of it.
d. This legitimizes ADJUSTABLE-ARRAY-P as an appropriate predicate to
determine whether ADJUST-ARRAY will reliably succeed.
This is consistent with both Position 1 and Position 2.
e. If ADJUST-ARRAY is invoked on an array that was created without
supplying :ADJUSTABLE true, an `array not adjustable' error
``should be signaled'' unless ADJUSTABLE-ARRAY-P returns true on
that array (in which case it must not signal an `array not adjustable'
error).
This is consistent with both Position 1 and Position 2.
Therefore, ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9) is a change to
CLtL, and in fact, Point 3 (and Consequence C) is a major change.
-rpg-
∂22-Mar-89 0845 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89 08:45:33 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562901; Wed 22-Mar-89 11:44:59 EST
Date: Wed, 22 Mar 89 11:44 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
To: Richard P. Gabriel <rpg@lucid.com>
cc: x3j13@SAIL.STANFORD.EDU
In-Reply-To: <8903220438.AA22664@challenger>
Message-ID: <19890322164453.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 21 Mar 89 20:38:38 PST
From: Richard P. Gabriel <rpg@lucid.com>
[603 lines deleted]
Therefore, ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9) is a change to
CLtL, and in fact, Point 3 (and Consequence C) is a major change.
Show us any conforming program that would be harmed by this change (if
it is a change, and I don't believe your arguments that it is a change)
"c. There is no specified way to create an array that is non-simple."
∂22-Mar-89 0931 X3J13-mailer Issue: SETF-MULTIPLE-STORE-VARIABLES (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89 09:31:05 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562950; Wed 22-Mar-89 12:30:11 EST
Date: Wed, 22 Mar 89 12:29 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: SETF-MULTIPLE-STORE-VARIABLES (Version 2)
To: X3J13@SAIL.STANFORD.EDU
cc: Pavel.pa@XEROX.COM, GSB@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19890322172956.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
This proposal didn't quite make it to the January meeting, due to
unclear responsibilities for who was supposed to update it from the
discussion. I have filled the gap and made the changes implied by the
discussion back in December of last year. We can't vote on this if
someone invokes the two-week rule, but perhaps no one will.
Issue: SETF-MULTIPLE-STORE-VARIABLES
References: CLtL, pp.93-107
Lisp Pointers, v2n2, pp.27-41
Category: ADDITION
Edit history: Version 1, 5-Dec-88, Pavel
Version 2, 22-Mar-89, Moon, simplify, update from discussion
Problem description:
The description of GET-SETF-METHOD-MULTIPLE-VALUE on page 107 of CLtL
states that there are no cases in Common Lisp that allow multiple values
to be stored into a generalized variable. This is seen by some as an
arbitrary decision in light of the fact that a very reasonable semantics
exists for multiple values being assigned by several Common Lisp macros,
including SETF. The rationale on page 103 of CLtL suggests that this
decision might be changed in the future.
Proposal (SETF-MULTIPLE-STORE-VARIABLES:ALLOW):
Extend the semantics of the macros SETF, PSETF, SHIFTF, ROTATEF, and
ASSERT to allow "places" whose SETF methods have more than one "store
variable". In such cases, the macros accept as many values from the
newvalue form as there are store variables. As usual, extra values
are ignored and missing values default to NIL.
Extend the long form of DEFSETF to allow the specification of more
than one "store variable", with the obvious semantics.
Clarify that GET-SETF-METHOD signals an error if there would be more
than one store-variable.
Test Cases/Examples:
(defstruct region width height)
(defun region-size (region)
(values
(region-width region)
(region-height region)))
(defsetf region-size (region) (width height)
`(values
(setf (region-width ,region) ,width)
(setf (region-height ,region) ,height)))
(setf my-reg (make-region :width 10 :height 20))
=> #S(REGION :WIDTH 10 :HEIGHT 20)
(region-size my-reg)
=> 10
20
(setf (region-size my-reg) (values 30 40))
=> 30
40
(region-size my-reg)
=> 30
40
Rationale:
This change removes an artificial restriction on the semantics of
several Common Lisp macros, allowing a broader set of contexts in
which generalized variables can be used. For example, it is not
difficult to write a reasonable SETF method for the VALUES function,
yielding a powerful MULTIPLE-VALUE-SETF form:
(setf (values (car a) (gethash b 'c) (aref d 13))
(some-hairy-computation))
In the language as currently defined, this example would have to be
written:
(multiple-value-bind (x y z)
(some-hairy-computation)
(setf (car a) x
(gethash b 'c) y
(aref d 13) z))
Many other (perhaps more compelling) examples of generalized variables
holding more than one value can easily be imagined. Their use,
however, is severely discouraged by Common Lisp as defined in CLtL,
since none of the built-in macros will accept them.
The clarification of GET-SETF-METHOD makes explicit what is implied
by CLtL (CLtL uses the word "guarantee", whose relationship to
signalling of errors is unclear).
Current practice:
I do not know of any implementations that allow all of this extension.
Xerox Lisp does not signal an error, but this is probably due to a bug
in GET-SETF-METHOD. Lucid signals an error in GET-SETF-METHOD.
Symbolics Genera supports the proposal in SETF and PSETF, but not in
SHIFTF, ROTATEF, and ASSERT.
Cost to Implementors:
A relatively minor fix to each of the affected macros suffices. For
example, to fix SETF itself, one need only call
GET-SETF-METHOD-MULTIPLE-VALUE instead of GET-SETF-METHOD and emit a
MULTIPLE-VALUE-BIND instead of a LET for binding the store variables.
Cost to Users:
This is an upward-compatible change; no user code must change.
Cost of non-adoption:
Yet another non-uniformity in the language, yet another piece of
mechanism without a clear use (GET-SETF-METHOD-MULTIPLE-VALUE).
Benefits:
Wider applicability of a reasonably nice abstraction, the removal of
an artificial prohibition.
Aesthetics:
People may disagree about whether this is a simplification or not. I
am firmly on the side that believes that such removal of
non-uniformities is a simplifying force in the language.
Discussion:
Pavel supports this proposal.
Moon supports this proposal except he is not sure about the
inclusion of ASSERT.
GSB suggests that this is a clarification rather than an addition,
because the lack of any predefined setf-methods that use multiple
store variables should not mean that SETF, etc. should not work with
such a setf-method if the user defined one. The problem is that CLtL
examples such as the ones for SHIFTF on p.98 and the simplified
definition for SETF on p.107 contradict this proposal, and might have
been taken as specifications, rather than simplified examples, by
some readers.
Predefined SETF methods for such functions as VALUES, CONS, and VECTOR
could have been proposed, but we refrained. This proposal is necessary
to allow the user to write such methods for himself, but if this
proposal is adopted those setf-methods are very easy to write in
a portable fashion.
∂22-Mar-89 1401 X3J13-mailer **DRAFT** issue: PATHNAME-COMPONENT-CASE (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89 14:01:14 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563174; Wed 22-Mar-89 17:00:57 EST
Date: Wed, 22 Mar 89 17:00 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue: PATHNAME-COMPONENT-CASE (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890322170040.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
>>> PLEASE DO -NOT- REPLY TO THIS ISSUE NOW <<<
At this point, probably no one will read what you would write
anyway. Instead, think about the issue and organize your thoughts
for in-person discussion at the meeting.
There was a lot of discussion on this issue. The Cleanup committee is
not in agreement on its disposition. However, the issue is a real one
that we cannot afford to overlook. See additional comments at the end
for a survey of points of contention.
-kmp
-----
Issue: PATHNAME-COMPONENT-CASE
References: Pathnames (pp410-413),
MAKE-PATHNAME (p416),
PATHNAME-HOST (p417),
PATHNAME-DEVICE (p417),
PATHNAME-DIRECTORY (p417),
PATHNAME-NAME (p417),
PATHNAME-TYPE (p417)
Category: CHANGE
Edit history: 1-Jul-88, Version 1 by Pitman
Status: For Internal Discussion
Problem Description:
Issues of case in pathnames are a major source of problems.
In some file systems, the canonical case is lowercase, in some
uppercase, in some mixed.
In some file systems, case matters, in others it does not.
(NAMESTRING (MAKE-PATHNAME :NAME "FOO" :TYPE "LISP"))
will produce an `ugly' file name like "FOO.LISP" in many (but not all)
Common Lisp implementations talking to Unix, for example.
(NAMESTRING (MAKE-PATHNAME :NAME "foo" :TYPE "lisp"))
might produce an `ugly' file name like "↑Vf↑Vo↑Vo.↑Vl↑Vi↑Vs↑Vp"
in a Common Lisp implementation talking to a Tops-20.
Problems like this make it difficult to use MAKE-PATHNAME for much of
anything without corrective (non-portable) code.
Other problems occur in merging because doing
(NAMESTRING (MERGE-PATHNAMES (MAKE-PATHNAME :HOST "MY-TOPS-20" :NAME "FOO")
(PARSE-NAMESTRING "MY-UNIX:x.lisp")))
should probably return "MY-TOPS-20:FOO.LISP" but in fact might return
"MY-TOPS-20:FOO.↑Vl↑Vi↑Vs↑Vp" in some implementations.
Problems like this make it difficult to use any merging primitives for
much of anything without corrective (non-portable code).
Proposal (PATHNAME-COMPONENT-CASE:CANONICALIZE):
Designate a treatment for case in pathname components which is
distinct from the treatment of case in the namestrings. The treatment
should be invariant across operating systems.
If a string given to MAKE-PATHNAME, or returned by any of the
PATHNAME-xxx accessor operations, is all uppercase, it is said to
designate a name in the system's "canonical case".
If a string given to MAKE-PATHNAME, or returned by any of the
PATHNAME-xxx accessor operations, is all lowercase, it is said to
designate a name in the system's "anticanonical case".
If a string given to MAKE-PATHNAME, or returned by any of the
PATHNAME-xxx accessor operations, is mixed case, it is said
designate a name in exactly the indicated case.
Functions such as PARSE-NAMESTRING and NAMESTRING which convert
from or to native host syntax will perform any necessary conversions
from internal syntax.
Note: In fact, this proposal does not require an implementation to
change its internal representation. It only requires the CL-defined
accessors to behave as if the internal representation had been changed.
Whether the actual internal representation is changed is still up to an
implementation. A consequence of this is that if pathnames print
in a way that shows the components individually (such as #S), they
are not constrained to print the components in any particular case;
they are constrained only to have definite syntax conventions and to
be able to invert those conventions at the appropriate time. Any change
to the way pathnames print is beyond the scope of this proposal.
Test Case:
(PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")) => "FOO"
(PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"
Rationale:
This does not solve the whole pathname problem, but it does improve
the situation for a clearly defined set of very common problems.
Current Practice:
Symbolics Genera implements this behavior.
Cost to Implementors:
While this proposal is compatible with CLtL, it may not be compatible with
the implementations of CLtL which some implementations have chosen.
It is possible to isolate the forced changes to the referenced functions
(MAKE-PATHNAME and the PATHNAME-xxx accessors). Existing functions can be
renamed, and new functions with the same name can be introduced which simply
encapsulate case conversion. No further change is forced.
It may, however, be desirable for an implementation to make a more complete
overhaul of their representation. In implementations where the implementors
feel a need to do this, the amount of work may be considerably greater.
Cost to Users:
Technically, this change is upward compatible.
In fact, since the existing CLtL spec is so poor, nearly everyone relies
heavily on implementation-specific behavior since there is little other
choice. As such, any change is almost certain to break lots of programs,
in usually superficial but nevertheless important ways. However, if we
really make the pathname facility more portable, the user community may be
willing to bear the consequences of these changes.
Cost of Non-Adoption:
We would be contributing to the perpetuation of the existing fiasco of a
pathname system.
Benefits:
The major costs of non-adoption would be avoided.
Aesthetics:
More code is required, but the code supports a simpler user model.
Anything that simplifies the user model of pathnames is going to be an
improvement.
Discussion:
Pitman suports PATHNAME-COMPONENT-CASE:CANONICALIZE.
-------------------------------------------------------------------
There was a lot of debate internally on CL-Cleanup about this one
which reached no resolution. Rather than include that discussion, I
will sum up what I think are the main discussion points:
- Uppercase was proposed as the canonical case because it seemed
most consistent with other parts of the language which are forced
to use a canonical case (such as symbol names and arguments to
macro character handlers).
Some people wish we would use lowercase because they think more
file systems are lowercase.
Note well that the choice of a case as the `canonical case'
internal to Lisp has no technical effect on your ability to
create filenames in upper, lower, or mixed case under this
proposal. This argument is purely an aesthetic one.
The Symbolics file system (upon which this proposal is based)
uses lowercase as the preferred case, and yet the use of uppercase
canonical case has caused no serious technical problems in the
five or so years that we've field tested this appraoch in
an environment that depends critically on heavy use of a variety
of file systems from the same lisp image. This is not a
pie-in-the-sky idea -- it is implemented and has stood the test of time.
- This proposal suggests that functions like PATHNAME-NAME return
and that make-pathname accept strings which are in the interchange
(canonical) case rather than in the native file system case so that
pathname components can be retrieved from one pathname and stored
in a second without regard to whether those two pathnames agreed on
native case.
Some people suggested that PATHNAME-NAME and MAKE-PATHNAME should
work non-portably, using native case information, and that you should
have to do more work (e.g., supply a keyword argument) to get portable
code. This strikes me as incompatible with our goals but is technically
a possible position to take.
Others suggested that two sets of functions should be available --
one set for native case (e.g., MAKE-FILENAME, FILENAME-NAME, ...)
and one for portable case (e.g., MAKE-PATHNAME, PATHNAME-NAME, ...).
These would make the same kind of object -- they would just support
different views on the set of operations that you might want on the
object. If you follow this approach, the issues become ``who gets
which names'' and ``does this make the language gratuitously bloated''?
Some people who wanted parallel paradigms (one for native case, one
for an interchange/canonical case) seemed to be willing to give up
that desire if the canonical case was coincidentally chosen to be the
same as the native case for the file system they worked with.
``I'll compromise as long as I don't have to change.''
- Some people don't use multiple file systems in the same core image
and don't realize how critical an issue this is to those of use who do.
THE BOTTOM LINE:
Users deal with this problem day in and day out as they move back and
forth between different systems. The solution is within our grasp
technically -- the key issues to be resolved are aesthetic and political,
not technical. In the end, users won't want to hear about the political
roadblocks. They are trusting us to come up with a solution and we should
come through. Please be prepared to come at this issue constructively. I
thank you, and our users will ultimately thank you.
∂22-Mar-89 1900 X3J13-mailer Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4)
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89 19:00:00 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by Riverside.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 325245; Wed 22-Mar-89 21:59:33 EST
Date: Wed, 22 Mar 89 21:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4)
To: X3J13@SAIL.STANFORD.EDU
Message-ID: <19890323025928.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
This is a last minute update of this issue to fix the problems found
during discussion of the previous version. I have fixed typos,
including some critical ones that made the proposal impossible to
understand, standardized terminology, and added specifications for
merging of relative directories and for the subset used in
non-hierarchical file systems.
Issue: PATHNAME-SUBDIRECTORY-LIST
References: Pathnames (pp410-413), MAKE-PATHNAME (p416),
PATHNAME-DIRECTORY (p417)
Category: CHANGE
Edit history: 18-Jun-87, Version 1 by Ghenis.pasa@Xerox.COM
05-Jul-88, Version 2 by Pitman (major revision)
28-Dec-88, Version 3 by Pitman (merge discussion)
22-Mar-89, Version 4 by Moon (fix based on discussion)
Status: Trying to be Released
Related-Issues: PATHNAME-COMPONENT-CASE
Problem Description:
It is impossible to write portable code that can produce a pathname
in a subdirectory of a hierarchical file system. This defeats much of
the purpose of having an abstraction like pathname.
According to CLtL, only a string is a portable value for the directory
component of a pathname, thus in order to denote a subdirectory, the
use of separators (such as dots, slashes, or backslashes) would be
necessary. The very fact that such syntax varies from host to host
means that although the representation might be "portable", the code
using that representation is not portable.
This problem is even worse for programs running on machines on a network
that can retrieve files from multiple hosts, each using a different OS
and thus a different subdirectory delimiter.
Related problems:
- In some implementations "FOO.BAR" might denote the "BAR" subdirectory
of "FOO", while in other implementations it would denote a top-level
directory, because "." is not the separator. To be safe, portable
programs must avoid all potential separators.
- Even in implementations where "." is the separator, "FOO.BAR" may be
recognized by some to mean the "BAR" subdirectory of "FOO" and by others
to mean `a seven letter directory with "." being a superquoted part of
its name'.
- In fact, CLtL does not even say for toplevel directories whether
the directory delimiter characters are part of the string. eg, is
"foo" or "/foo" the directory component for a unix pathname
"/foo/bar.lisp". Similarly, is "[FOO]" or "FOO" the directory
component for a VMS pathname "[FOO]ME.LSP"?
Proposal (PATHNAME-SUBDIRECTORY-LIST:NEW-REPRESENTATION)
Remove the "structured" directory feature mentioned on CLtL p.412.
Allow the value of a pathname's directory component to be a list. The
car of the list may be either of the symbols :ABSOLUTE or :RELATIVE.
Each remaining element of the list is a string or one of the keyword
symbols listed below. Each string names a single level of directory
structure. The strings should contain only the directory names
themselves -- no separator characters.
A list whose car is the symbol :ABSOLUTE represents a directory path
starting from the root directory. The list (:ABSOLUTE) represents
the root directory. The list (:ABSOLUTE "foo" "bar" "baz") represents
the directory called "/foo/bar/baz" in Unix [except possibly for
alphabetic case -- that is the subject of a separate issue].
A list whose car is the symbol :RELATIVE represents a directory path
starting from a default directory. The list (:RELATIVE) has the same
meaning as NIL. The list (:RELATIVE "foo" "bar") represents the
directory named "bar" in the directory named "foo" in the default
directory [except possibly for alphabetic case -- that is the subject
of a separate issue].
In place of a string, at any point in the list, keyword symbols may occur
to indicate special file notations. The following symbols have standard
meanings; they may not be meaningful for all operating systems, and are
intended for use only on those operating systems where they have meaning.
Implementations are permitted to add additional keyword symbols if
necessary to represent features of their file systems.
:WILD - Wildcard match of one level of directory structure.
:WILD-INFERIORS - Wildcard match of any number of directory levels.
:UP - Go upward in directory structure (semantic).
:BACK - Go upward in directory structure (syntactic).
"Syntactic" means that the action of :BACK depends only on the pathname
and not on the contents of the file system. "Semantic" means that the
action of :UP depends on the contents of the file system; to resolve
a pathname containing :UP to a pathname whose directory component
contains only :ABSOLUTE and strings requires probing the file system.
:UP differs from :BACK only in file systems that support multiple
names for directories, perhaps via symbolic links. For example,
suppose that there is a directory
(:ABSOLUTE "X" "Y" "Z")
linked to
(:ABSOLUTE "A" "B" "C")
and there also exist directories
(:ABSOLUTE "A" "B" "Q")
(:ABSOLUTE "X" "Y" "Q")
then
(:ABSOLUTE "X" "Y" "Z" :UP "Q")
designates
(:ABSOLUTE "A" "B" "Q")
while
(:ABSOLUTE "X" "Y" "Z" :BACK "Q")
designates
(:ABSOLUTE "X" "Y" "Q")
If a string is used as the value of the :DIRECTORY argument to
MAKE-PATHNAME, it should be the name of a toplevel directory and
should not contain any directory delimiter characters. Specifying a
string, str, is equivalent to specifying the list (:ABSOLUTE str).
Specifying the symbol :WILD is equivalent to specifying the list
(:ABSOLUTE :WILD-INFERIORS), or (:ABSOLUTE :WILD) in a
non-hierarchical file system.
The PATHNAME-DIRECTORY function never returns a string nor :WILD; it
always returns NIL, :UNSPECIFIC, or a list.
In non-hierarchical file systems, the only valid list values for the
directory component of a pathname are (:ABSOLUTE string) and
(:ABSOLUTE :WILD). :RELATIVE directories and the keywords
:WILD-INFERIORS, :UP, and :BACK are not used in non-hierarchical file
systems.
Pathname merging treats a relative directory specially. Let
<pathname> and <defaults> be the first two arguments to
MERGE-PATHNAMES. If (PATHNAME-DIRECTORY <pathname>) is a list whose
car is :RELATIVE, and (PATHNAME-DIRECTORY <defaults>) is a list, then
the merged directory is the value of
(APPEND (PATHNAME-DIRECTORY <defaults>)
(CDR (PATHNAME-DIRECTORY <pathname>)))
except that if the resulting list contains an element other than :BACK
or :WILD-INFERIORS, immediately followed by :BACK, both of them are
removed. This removal of redundant :BACKs is repeated as many times
as possible. If (PATHNAME-DIRECTORY <defaults>) is not a list, the
merged directory is
(OR (PATHNAME-DIRECTORY <pathname>) (PATHNAME-DIRECTORY <defaults>))
A relative directory in the pathname argument to a function such as
OPEN is merged with *DEFAULT-PATHNAME-DEFAULTS* before accessing the
file system.
Test Cases/Examples:
(PATHNAME-DIRECTORY (PARSE-NAMESTRING "[FOO.BAR]BAZ.LSP")) ;on VMS
=> (:ABSOLUTE "FOO" "BAR")
(PATHNAME-DIRECTORY (PARSE-NAMESTRING "/foo/bar/baz.lisp")) ;on Unix
=> (:ABSOLUTE "foo" "bar")
or (:ABSOLUTE "FOO" "BAR")
If PATHNAME-COMPONENT-CASE:CANONICALIZE passes, only the 2nd return value.
(PATHNAME-DIRECTORY (PARSE-NAMESTRING "../baz.lisp")) ;on Unix
=> (:RELATIVE :UP)
(PATHNAME-DIRECTORY (PARSE-NAMESTRING "/foo/bar/../mum/baz")) ;on Unix
=> (:ABSOLUTE "foo" "bar" :UP "mum")
(PATHNAME-DIRECTORY (PARSE-NAMESTRING ">foo>**>bar>baz.lisp")) ;on LispM
=> (:ABSOLUTE "FOO" :WILD-INFERIORS "BAR")
(PATHNAME-DIRECTORY (PARSE-NAMESTRING ">foo>*>bar>baz.lisp")) ;on LispM
=> (:ABSOLUTE "FOO" :WILD "BAR")
Rationale:
This would allow programs to usefully deal with hierarchical file
systems, which are by far the most common file system type.
Current Practice:
Symbolics Genera implements something very similar to this. The main
differences are:
- In Genera, there is no :ABSOLUTE keyword at the head of the list.
This has been shown to cause some problems in dealing with root
directories. Genera represents the root directory by a keyword
symbol (rather than a list) because the list representation
was not adequately general.
- Genera represents Unix ".." as :UP, but deals with :UP
syntactically, not semantically.
Cost to Implementors:
In principle, nothing about the implementation needs to change except
the treatment of the directory component by MAKE-PATHNAME and
PATHNAME-DIRECTORY. The internal representation can otherwise be left
as-is if necessary.
Implementations such as Genera that already have hierarchical directory
handling will have to make an incompatible change to switch to what
is proposed here.
For implementations that choose to rationalize this representation
throughout their internals and any other implementation-specific
accessors, the cost will be necessarily higher.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Serious portability problems would continue to occur. Programmers would be
driven to the use of implementation-specific facilities because the need
for this is frequently impossible to ignore.
Benefits:
The serious costs of non-adoption would be avoided.
Aesthetics:
This representation of hierarchical pathnames is easy to use and quite
general. Users will probably see this as an improvement in the aesthetics.
Discussion:
This issue was raised a while back but no one was fond of the particular
proposal that was submitted. This is an attempt to revive the issue.
The original proposal, to add a :SUBDIRECTORIES component to a
pathname, was discarded because it imposed an unnatural distinction
between a toplevel directory and its subdirectories. Pitman's guess is
the the idea was to try to make it a compatible change, but since most
programmers will probably want to change from implementation-specific
primitives to portable ones anyway, that's probably not such a big
deal. Also, there might have been some programs which thought the
change was compatible and ended up ignoring important information (the
:SUBDIRECTORIES component). Pitman thought it would be better if
people just accepted the cost of an incompatible change in order to
get something really pretty as a result.
Moon doesn't like having both :UP and :BACK, but admits that some
file systems do it one way and some do it the other.
To keep it simple, we chose not to add to this issue the functions
DIRECTORY-PATHNAME-AS-FILE and PATHNAME-AS-DIRECTORY, which convert
the name of a directory from or to the directory component of a file
inferior to that directory. This conversion is system-dependent, for
example TOPS-20 appends a type field and Unix does not. Also in some
systems the root directory has a name and in others it doesn't. Of
course these functions signal an error in non-hierarchical file
systems.
∂22-Mar-89 2031 X3J13-mailer Issue: PATHNAME-COMPONENT-CASE (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89 20:30:42 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563397; Wed 22-Mar-89 23:30:16 EST
Date: Wed, 22 Mar 89 23:30 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-COMPONENT-CASE (Version 2)
To: X3J13@SAIL.STANFORD.EDU
Message-ID: <19890323043004.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
I updated and rewrote this issue based on the discussion last Summer and
Autumn that followed the publication of version 1 within the cleanup
committee. Perhaps we can use this as the basis for a constructive
discussion and get this issue out of the way.
This issue contains four alternative proposals.
Issue: PATHNAME-COMPONENT-CASE
References: Pathnames (pp410-413),
MAKE-PATHNAME (p416),
PATHNAME-HOST (p417),
PATHNAME-DEVICE (p417),
PATHNAME-DIRECTORY (p417),
PATHNAME-NAME (p417),
PATHNAME-TYPE (p417)
Category: CHANGE
Edit history: 1-Jul-88, Version 1 by Pitman
22-Mar-89, Version 2 by Moon, update and rewrite
Status: Trying to be ready for release
Problem Description:
Issues of alphabetic case in pathnames are a major source of problems.
In some file systems, the customary case is lowercase, in some
uppercase, in some mixed. In some file systems, case matters, in
others it does not.
There are two kinds of portability problems connected with case in
pathnames: moving programs from one Common Lisp to another, and moving
pathname component values from one file system to another. To solve
the first problem, all Common Lisp implementations that support a
particular file system must use compatible representations for
pathname component values. To solve the second problem, there must be
a canonical representation for pathname component values that means
the same thing on all file systems.
The desire for a canonical representation for pathname component
values directly conflicts with the desire among programmers who only
use one file system to work with the local conventions and not to
have to think about issues of porting to other file systems. The
canonical representation cannot be the same as every local
convention, since they vary.
In the current anarchy of pathname component case conventions:
(NAMESTRING (MAKE-PATHNAME :NAME "FOO" :TYPE "LISP"))
will produce foo.lisp in some Unix Common Lisp implementations
and will produce FOO.LISP in other Unix Common Lisp implementations.
(NAMESTRING (MAKE-PATHNAME :NAME "foo" :TYPE "lisp"))
will produce FOO.LISP in some Tops-20 Common Lisp implementations
and will produce "↑Vf↑Vo↑Vo.↑Vl↑Vi↑Vs↑Vp"in other Tops-20 Common
Lisp implementations.
Problems like this make it difficult to use MAKE-PATHNAME for much of
anything without corrective (non-portable) code.
Other problems occur in merging because doing
(NAMESTRING (MERGE-PATHNAMES (MAKE-PATHNAME :HOST "MY-TOPS-20" :NAME "FOO")
(PARSE-NAMESTRING "MY-UNIX:x.lisp")))
should probably return "MY-TOPS-20:FOO.LISP" but in fact might return
"MY-TOPS-20:FOO.↑Vl↑Vi↑Vs↑Vp" in some implementations.
Problems like this make it difficult to use any merging primitives for
much of anything without corrective (non-portable) code.
Proposal (PATHNAME-COMPONENT-CASE:CANONICALIZE):
Designate a treatment for case in pathname components which is
distinct from the treatment of case in the namestrings. The treatment
should be invariant across operating systems. Namestrings use local
file system case conventions, pathname components use common case
conventions.
Arbitrarily choose uppercase as the common (or universal) case.
If a string given to MAKE-PATHNAME, or returned by any of the
PATHNAME-xxx accessor operations, is all uppercase, it is said to
designate a name in the system's "canonical case".
If a string given to MAKE-PATHNAME, or returned by any of the
PATHNAME-xxx accessor operations, is all lowercase, it is said to
designate a name in the system's "anticanonical case".
If a string given to MAKE-PATHNAME, or returned by any of the
PATHNAME-xxx accessor operations, is mixed case, it is said to
designate a name in exactly the indicated case.
Functions such as PARSE-NAMESTRING and NAMESTRING which convert from
or to local file system syntax will perform any necessary conversions
between "canonical case" and the host's customary case, and between
"anticanonical case" and the opposite of the host's customary case.
Proposal (PATHNAME-COMPONENT-CASE:NEW-COMMON-ACCESSORS):
Add new pathname component accessor functions that return values
translated to the common case defined above. Use the local file
system case conventions in the existing pathname component accessor
functions. The new accessors are named PATHNAME-COMMON-DEVICE,
PATHNAME-COMMON-DIRECTORY, PATHNAME-COMMON-NAME, and
PATHNAME-COMMON-TYPE.
Add new keyword arguments to MAKE-PATHNAME that accept values in the
the common case defined above and translate to the host's customary
case. Use the local file system case conventions in the existing
keyword arguments to MAKE-PATHNAME. The new keyword arguments are
named :COMMON-DEVICE, :COMMON-DIRECTORY, :COMMON-NAME, and
:COMMON-TYPE.
Proposal (PATHNAME-COMPONENT-CASE:NEW-LOCAL-ACCESSORS):
Do everything proposed for PATHNAME-COMPONENT-CASE:CANONICALIZE,
and in addition:
Add new pathname component accessor functions that return values in
the local file system case conventions. The new accessors are named
PATHNAME-LOCAL-DEVICE, PATHNAME-LOCAL-DIRECTORY, PATHNAME-LOCAL-NAME,
and PATHNAME-LOCAL-TYPE.
Add new keyword arguments to MAKE-PATHNAME that accept values in the
local file system case conventions. The new keyword arguments are
named :LOCAL-DEVICE, :LOCAL-DIRECTORY, :LOCAL-NAME, and :LOCAL-TYPE.
Proposal (PATHNAME-COMPONENT-CASE:KEYWORD-ARGUMENT):
Add a keyword argument :CASE to MAKE-PATHNAME and the PATHNAME-xxx
accessors, indicating whether common or local conventions should be
followed. The possible values for the argument are :COMMON and
:LOCAL. The default is :COMMON.
Test Case:
Under PATHNAME-COMPONENT-CASE:CANONICALIZE:
(PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")) => "FOO"
(PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"
Under PATHNAME-COMPONENT-CASE:NEW-COMMON-ACCESSORS:
(PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")) => "foo"
(PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"
(PATHNAME-COMMON-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")) => "FOO"
(PATHNAME-COMMON-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"
Under PATHNAME-COMPONENT-CASE:NEW-LOCAL-ACCESSORS:
(PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")) => "FOO"
(PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"
(PATHNAME-LOCAL-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")) => "foo"
(PATHNAME-LOCAL-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"
Under PATHNAME-COMPONENT-CASE:KEYWORD-ARGUMENT:
(PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")
:CASE :COMMON) => "FOO"
(PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")
:CASE :COMMON) => "FOO"
(PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")
:CASE :LOCAL) => "foo"
(PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")
:CASE :LOCAL) => "FOO"
Rationale:
This does not solve the whole pathname problem, but it does improve
the situation for a clearly defined set of very common problems.
Together with the other pathname proposals, the behavior of pathnames
should be sufficiently consistent across Common Lisp implementations
and across file systems to allow portability of pathname-manipulating
programs.
Upper case is chosen as the canonical case for no better reason than
consistency with the canonical case for Lisp symbols.
PATHNAME-COMPONENT-CASE:CANONICALIZE minimizes the size of the
language by not adding any new functions. It assumes that pathname
operations using local file system conventions can be performed on
namestrings and that anything that calls MAKE-PATHNAME or the
PATHNAME-xxx accessors is portable code that is independent of the
local file system conventions.
PATHNAME-COMPONENT-CASE:NEW-COMMON-ACCESSORS assumes that the existing
MAKE-PATHNAME and PATHNAME-xxx accessor features are for programs that
only work on one file system and that more generally portable programs
should use new features.
PATHNAME-COMPONENT-CASE:NEW-LOCAL-ACCESSORS assumes that the existing
MAKE-PATHNAME and PATHNAME-xxx accessor features are for fully
portable programs but that PATHNAME-COMPONENT-CASE:CANONICALIZE is
insufficient and direct access to the local conventions is required.
PATHNAME-COMPONENT-CASE:KEYWORD-ARGUMENT assumes that access to both
conventions is necessary but introducing more functions is bad.
The default convention is the common one, assuming that most
programs are fully portable.
Note:
None of these proposals requires an implementation to change its
internal representation. They only require the canonical accessors to
behave as if the internal representation had been changed. Whether
the actual internal representation is changed is still up to an
implementation. A consequence of this is that if pathnames print in a
way that shows the components individually (such as #S), they are not
constrained to print the components in any particular case; they are
constrained only to have definite syntax conventions and to be able to
invert those conventions at the appropriate time. Any change to the
way pathnames print is beyond the scope of this proposal.
There should probably be a remark somewhere that says that portable
programs shouldn't expect to be able to create and/or access distinct
files whose pathname components differ only in case.
Current Practice:
Symbolics Genera implements something resembling
PATHNAME-COMPONENT-CASE:NEW-LOCAL-ACCESSORS except that the names use
"raw" rather than "local". The "raw" accessors are almost never used.
Symbolics Genera's own file system uses lower case as the customary
case, but transparent network access is available to file systems
using all known case conventions.
Many Common Lisp implementations that only deal with a single file
system implement something resembling
PATHNAME-COMPONENT-CASE:NEW-COMMON-ACCESSORS except without the
new accessors and keyword arguments.
Cost to Implementors:
While all of these proposals are compatible with CLtL, since CLtL is
so vague, they are not likely to be compatible with the
implementations of CLtL which some implementations have chosen.
It is possible to isolate the forced changes to the referenced functions
(MAKE-PATHNAME and the PATHNAME-xxx accessors). Existing functions can be
renamed, and new functions with the same name can be introduced which simply
encapsulate case conversion. No further change is forced.
It may, however, be desirable for an implementation to make a more complete
overhaul of their representation. In implementations where the implementors
feel a need to do this, the amount of work may be considerably greater.
Cost to Users:
Technically, this change is upward compatible.
In fact, since the existing CLtL spec is so poor, nearly everyone relies
heavily on implementation-specific behavior since there is little other
choice. As such, any change is almost certain to break lots of programs,
in usually superficial but nevertheless important ways. However, if we
really make the pathname facility more portable, the user community may be
willing to bear the consequences of these changes.
Cost of Non-Adoption:
We would be contributing to the perpetuation of the existing fiasco of a
pathname system.
Benefits:
The major costs of non-adoption would be avoided.
Aesthetics:
More code is required, but the code supports a simpler user model.
Anything that simplifies the user model of pathnames is going to be an
improvement.
Discussion:
Some people would rather use lowercase as the canonical case. The
decision is essentially arbitrary. Everywhere else in Common Lisp
where there is a canonical case, uppercase was chosen.
It has been proposed that the Common Lisp specification should include
specifications of the exact behavior of pathnames for several popular
operating systems, so that multiple implementations for those
operating systems would be compatible with each other. This proposal
does not attempt to do that, only to establish the coherent framework
within which it would be done.
In PATHNAME-COMPONENT-CASE:KEYWORD-ARGUMENT, some people want the
default for :CASE to be :LOCAL instead of :COMMON. I would have
written that up too, but I thought five proposals were too many.
∂23-Mar-89 0028 X3J13-mailer 20 March cs proposal
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 23 Mar 89 00:27:44 PST
Date: Wed, 22 Mar 89 15:01:01 PST
From: Thom Linden <baggins@IBM.com>
To: Common Lisp mailing <x3j13@sail.stanford.edu>
Message-ID: <890322.150101.baggins@almvma>
Subject: 20 March cs proposal
I've sent out the latest cs proposal again in LaTex format.
(Sorry, I have no public login and was unable to login to one
which Gregor offered.
Sandra, if possible please put a DVI file out on cs.utah.edu again)
I've again tried to incorporate many of the comments received. The
main features are:
-- The entire format was revamped! Appendix A no longer
exists; everything is in Chapter 2. The items which are
'voting' items are denoted by italized sections titled
PROPOSAL. All the proposals are numbered, some are
alternatives to prior proposals (and are marked ALTERNATIVE).
Anything not within a PROPOSAL section is simply discussion.
A fringe benefit is the document is only 22 pages.
-- I've tried to break up proposals which comments indicated
should be voted upon individually.
-- Some of the new/revised proposals suggested by comments:
-- Removing char-code-limit, char-code and code-char
-- Base-character is now based on
(upgraded-array-element-type 'standard-char)
-- A new function, find-external-char which returns
a character object given a coded character set
name and index.
-- Specifing the behavior of with-output-to-string
if no string is specified and
make-string-output-stream to produce a stream
that accepts all characters and returns
the most specialized string type that accommodates
the characters actually output.
-- Various 'too long' names were changed per comments.
For example, the new keyword argument to open is
now (simply) :external-code.
Regards,
Thom
∂23-Mar-89 0127 X3J13-mailer 20 March cs proposal part 1 of 1
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 23 Mar 89 01:25:02 PST
Date: Wed, 22 Mar 89 14:24:58 PST
From: Thom Linden <baggins@IBM.com>
To: Common Lisp mailing <x3j13@sail.stanford.edu>
Message-ID: <890322.142458.baggins@almvma>
Subject: 20 March cs proposal part 1 of 1
\documentstyle{report} % Specifies the document style.
\pagestyle{headings}
\title{\bf
Extensions to Common LISP to Support International
Character Sets}
\author{
Michael Beckerle\thanks{Gold Hill Computers} \and
Paul Beiser\thanks{Hewlett-Packard} \and
Jerry Duggan\thanks{Hewlett-Packard} \and
Robert Kerns\thanks{Independent consultant} \and
Kevin Layer\thanks{Franz, Inc.} \and
Thom Linden\thanks{IBM Research, Subcommittee Chair} \and
Larry Masinter\thanks{Xerox Research} \and
David Unietis\thanks{Lucid, Inc.}
}
\date{March 20, 1989} % Deleting this command produces today's date.
\begin{document}
\maketitle % Produces the title.
\setcounter{secnumdepth}{4}
\setcounter{tocdepth}{4}
\tableofcontents
%----------------------------------------------------------------------
%----------------------------------------------------------------------
\newtheorem{prop}{Proposal}[section]
\newfont{\cltxt}{cmr10}
\newfont{\clkwd}{cmtt10}
\newcommand{\apostrophe}{\clkwd '}
\newcommand{\bq}{\clkwd\symbol{'22}}
%----------------------------------------------------------------------
%----------------------------------------------------------------------
\chapter{Introduction}
This is a proposal to the X3 J13 committee
for both extending and modifying the Common LISP
language definition to provide a standard basis for Common LISP
support of the variety of characters used to represent the
native languages of the international community.
This proposal was created by the Character Subcommittee of X3 J13.
We would like to acknowledge discussions with T. Yuasa and other
members of the JIS Technical Working Group,
comments from members of X3 J13,
and the proposals \cite{ida87},
\cite{linden87}, \cite{kerns87}, and \cite{kurokawa88} for
providing the motivation and direction for these extensions.
As all these documents and discussions were created
expressly for LISP standardization usage,
we have borrowed freely from their ideas as well as the texts
themselves.
\section{Objectives}
The major objectives of this proposal are:
\begin{itemize}
\item To provide a consistent, well-defined scheme allowing support
of both very large character sets and multiple character sets.
\footnote{The distinction between the terms {\em character repertoire}
and {\em coded character set} is made later. The usage
of the term {\em character set},
avoided after this introduction, encompasses both terms.}
Many software applications are intended for international use, or
have requirements for incorporation of language elements of multiple
native languages within a single application.
Also, many applications require specialized languages including,
for example, scientific and typesetting symbols.
In order
to ensure some portability of these applications, data expressed in
a mixture of these
languages must be treated uniformly by the
software language.
All character and string manipulations should operate uniformly,
regardless of the character set(s) of the character objects.
This applies to array indexing, readtable definitions, read
symbol construction and I/O operations.
\item To ensure efficient performance of string and character
operations.
Many native
languages, such as Japanese and Chinese, use character
sets which contain more characters than the Latin alphabet.
Supporting larger sized character sets frequently means employing
larger data fields to uniquely encode each character.
Common LISP implementations using
larger sized character sets can
incur performance penalties in terms
of space, time, or both.
The use of large and/or multiple character sets by an
implementation
implies the need for a more complex character type representation.
Given a more complex character representation, the efficiency
of language operations on characters (e.g. string operations)
could be affected.
\item To assure forward compatibility of the proposed model
and definition with existing Common LISP implementations.
Developers should not be required to re-write large amounts of either
LISP code or data representations in order to apply the proposed
changes to existing implementations.
The proposed changes should provide an easy
portability path for existing code to many possible implementations.
\end{itemize}
There are a number of issues, some under the general rubric of
internationalization, which this proposal does {\em not} cover.
Among these issues are:
\begin{itemize}
\item Time and date formats
\item Monetary formats
\item Numeric punctuation
\item Fonts
\item Lexicographic orderings
\item Right-to-left and bidirectional languages
\end{itemize}
%----------------------------------------------------------------------
%----------------------------------------------------------------------
%----------------------------------------------------------------------
%----------------------------------------------------------------------
\chapter{Overview}
We use several terms within this document which
are new in the context of Common LISP.
Definitions for the following prominent
terms are provided for the reader's convenience.
A {\em character repertoire} defines a collection of characters
independent of their specific rendered image or font. This
corresponds to the mathematical notion of a {\em set}
\footnote{We avoid the term {\em character set} as it has been
(over)used in the context of character repertoire as well
as in the context of coded character set.}.
Character
repertoires are specified independent of coding and their characters
are only identified with a unique {\em character label},
a graphic symbol, and
a character description.
A {\em coded character set} is a character repertoire plus
an {\em encoding} providing a unique mapping between each character
and a number which serves as the character representation.
There are numerous internationally standardized coded character
sets; for example, \cite{iso8859/1} and \cite{iso646}.
A character may be included in one or more character repertoires.
Similarly, a character may be included in one or more
coded character sets. For example, the Latin letter "A" is contained
in the coded character set standards: ISO 8859/1, ISO 8859/2,
ISO 6937/2, and others.
To universally identify each character, we define a unique
collection of repertoires called {\em character
registries} as a partitioning of all characters.
That is, each character is included
in one and only one character registry.
In Common LISP a {\em character} data object is identified by its
{\em character code}, a unique numerical code.
Each character code is composed from
a character registry and a character label.
Character data objects which are classified as {\em graphic},
or displayable, are each associated with a {\em glyph}. The
glyph is the visual representation of the character.
Character data objects which are not graphic are classified
as {\em control}.
The primary purpose of introducing these terms is to provide a
consistent naming to Common LISP concepts which are related
to those found in ISO standardization of coded
character sets.
\footnote{The bibliography includes several relevant ISO
coded character set standards.}
They also serve as a demarcation between these
standardization activities. For example, while Common LISP is free to
define unique manipulation facilities for characters, registries
and coded character sets, it should
not define standard coded character sets nor standard character
registries.
A secondary purpose is to detach the language specification from
underlying hardware representation. From a language
specification viewpoint it is inconsequential whether
characters occupy one or more (8-bit) bytes or whether
a Common LISP implementation's
internal representation for characters is distinct from or identical
to any of the numerous
external representations (for example, the text interchange
representation \cite{iso6937/2}).
We specifically do not propose any standard coded character sets.
A final purpose is to serve as a basis for terminology within the
standard language specification.
\begin{prop}
The terminology introduced in this proposal will be included
in the language specification at the discretion of the editor.
\end{prop}
%----------------------------------------------------------------------
\section{Character Identity}
Characters are uniquely distinguished by their codes,
which are drawn from the set of
non-negative integers. That is, within Common LISP
a unique numerical code
is assigned to each semantically different character.
It is important to separate the notion of glyph from the notion of
character data object when defining a scheme under which issues of
identity can be rigorously decided by a computer language. Glyphs are
the visual aspects of characters, writable on surfaces, and sometimes
called 'graphics'. A language specification valid for more than a
narrow range of systems can only make assumptions about the existence
of {\em abstract} glyphs (for example, the Latin letter A) and not about
glyph variants (for example, the italicized Latin letter {\em A})
or characteristics of display devices.
The notion of attributes of character
objects within Common LISP has proven to be either not used or
not portable. The essential aspect of the following proposals is
to what extent attributes continue to be supported by the
language specifications.
\begin{prop}[Alternative A]
Remove all discussion of attributes from
the language specification. Add the following discussion:
\begin{quote}
Earlier versions of Common LISP incorporated {\em font} and
{\em bits} as attributes of character objects. These and other
supported attributes are considered implementation-defined
attributes and if supported by an implementation effect the
action of selected functions.
\end{quote}
All types, constants and functions
dealing with the {\em bits} and {\em font} attributes are either
removed or modified as follows:
\begin{itemize}
\item Modify {\clkwd char-=}: If two characters differ in any
implementation-defined attributes, then they are not {\clkwd char-=}.
\item Modify {\clkwd char-<}: If two characters have identical
implementation-defined attributes, then their ordering by
{\clkwd char}$<$ is consistent with the numerical ordering by the
predicate $<$ on
their code. (Similarly for {\clkwd char}$>$,
{\clkwd char}$>=$ and {\clkwd char}$<=$.)
\item Modify {\clkwd char-equal}:
The effect, if any, on {\clkwd char-equal} of each
implementation-defined attribute has to be specified as part of
the definition of that attribute (and similarly for
{\clkwd char-not-equal, char-lessp, char-greaterp,
char-not-greaterp, char-not-lessp}).
\item Modify {\clkwd char-upcase} and {\clkwd char-downcase}:
The effect of {\clkwd char-upcase} and {\clkwd char-downcase}
is to preserve implementation-defined attributes.
\item Modify {\clkwd read}: It is implementation dependent which
attributes are removed from symbol names.
It is implementation dependent which attributes are removed
from characters within double quotes.
\item Modify {\clkwd intern}: It is implementation dependent,
but consistent with the {\clkwd read} function,
which implementation-defined attributes are removed.
\item Modify {\clkwd digit-char}: remove the optional {\em font}
argument.
\item Modify {\clkwd code-char}: remove the optional {\em font}
and {\em bits} arguments.
\item Remove {\clkwd char-font-limit}
\item Remove {\clkwd char-bits-limit}
\item Remove {\clkwd int-char}
\item Remove {\clkwd char-int}
\item Remove {\clkwd char-bits}
\item Remove {\clkwd char-font}
\item Remove {\clkwd make-char}
\item Remove {\clkwd char-control-bit}
\item Remove {\clkwd char-meta-bit}
\item Remove {\clkwd char-super-bit}
\item Remove {\clkwd char-hyper-bit}
\item Remove {\clkwd char-bit}
\item Remove {\clkwd set-char-bit}
\item Redefine {\clkwd string-char} as implementation defined
as either {\clkwd base-character} or {\clkwd character}.
\item Modify readtable: If implementation-defined attributes
are supported, an implementation need not (but may) allow
for such characters to have syntax descriptions in the readtable.
Otherwise, all characters are representable in the readtable.
\end{itemize}
\end{prop}
\begin{prop}[Alternative B]
This is identical to all of Alternative A (above) except that
the function {\clkwd char-int} is retained for hashing purposes.
{\clkwd char-int} returns a non-negative integer encoding the
character object. The manner in which the integer is computed
is implementation dependent. In contrast to {\clkwd sxhash},
the result is not guaranteed independent of the particular
"incarnation" or "core image".
\end{prop}
With the elimination of {\em font} and {\em bits} from the
specification the usefulness of {\clkwd char-code} and {\clkwd
code-char} is diminished. They are no longer needed for constructing
characters.
The portable mechanisms for hashing are provided by
{\clkwd char-int} and {\clkwd sxhash}.
In addition, using {\clkwd char-code-limit} to iterate over
characters is extremely inefficient in implementations that
support large or user-defined repertoires.
\begin{prop}[Alternative C]
This an amendment to Alternative B (above).
\begin{itemize}
\item Remove {\clkwd char-code-limit}
\item Remove {\clkwd char-code}
\item Remove {\clkwd code-char}
\end{itemize}
\end{prop}
%----------------------------------------------------------------------
\section{Standard and Semi-Standard Characters}
The standard characters are the 96 characters used in the Common LISP
definition {\bf or their equivalents}.
This was the Common LISP \cite{steele84} definition, but
{\em equivalents} is a vague term.
The standard characters are not defined by their glyphs, but by their
roles within the language. There are two aspects to the roles of the
standard characters: one is their role in reader and format control
string syntax; the second is their role as components of the names of
all Common LISP
functions, macros, constants, and global variables. As
long as an implementation chooses 96 glyphs
and treats those 96 in a manner consistent with
the language's specification for the standard characters (e.g.
the naming of functions), it doesn't matter what glyphs the I/O
hardware uses to represent those characters: they are the standard
characters. Any program or
data text written wholly in those characters
is portable through simple code conversion.
\footnote{For example, the currency glyph, \$ , might be replaced
uniformly by the currency glyph available on a particular display.}
Additional mechanisms,
such as in \cite{kurokawa88}, which support establishment of
equivalency between otherwise distinct characters are not excluded by
this proposal.
\footnote{We believe this is an important issue but it requires
additional implementation experience. We also encourage
new proposals from JIS and ISO LISP Working Groups on this issue.}
\begin{prop}
The discussion of standard characters is
replaced by the following:
Common LISP requires all implementations to support a {\em standard}
character subrepertoire.
The Common LISP
standard character subrepertoire consists of
a newline \#$\backslash${\clkwd Newline}, the
graphic space character \#$\backslash${\clkwd Space},
and the following additional
ninety-four graphic characters or their equivalents:
\footnote{\cltxt \#$\backslash${\clkwd Space}
and \#$\backslash${\clkwd Newline} are omitted.
graphic labels and descriptions are from ISO 6937/2.
The first letter of the graphic Id categorizes the
character as follows: L - Latin, N - Numeric, S - Special
.}
{\small \begin{tabular}{||l|c|l||l|c|l||} \hline
Id & Glyph & Name or description
& Id & Glyph & Name or description
\\ \hline
LA01 & a & small a
& ND01 & 1 & digit 1
\\ \hline
LA02 & A & capital A
& ND02 & 2 & digit 2
\\ \hline
LB01 & b & small b
& ND03 & 3 & digit 3
\\ \hline
LB02 & B & capital B
& ND04 & 4 & digit 4
\\ \hline
LC01 & c & small c
& ND05 & 5 & digit 5
\\ \hline
LC02 & C & capital C
& ND06 & 6 & digit 6
\\ \hline
LD01 & d & small d
& ND07 & 7 & digit 7
\\ \hline
LD02 & D & capital D
& ND08 & 8 & digit 8
\\ \hline
LE01 & e & small e
& ND09 & 9 & digit 9
\\ \hline
LE02 & E & capital E
& ND10 & 0 & digit 0
\\ \hline
LF01 & f & small f
& SC03 & \$ & dollar sign
\\ \hline
LF02 & F & capital F
& SP02 & ! & exclamation mark
\\ \hline
LG01 & g & small g
& SP04 & " & quotation mark
\\ \hline
LG02 & G & capital G
& SP05 & \apostrophe & apostrophe
\\ \hline
LH01 & h & small h
& SP06 & ( & left parenthesis
\\ \hline
LH02 & H & capital H
& SP07 & ) & right parenthesis
\\ \hline
LI01 & i & small i
& SP08 & , & comma
\\ \hline
LI02 & I & capital I
& SP09 & \_ & low line
\\ \hline
LJ01 & j & small j
& SP10 & - & hyphen or minus sign
\\ \hline
LJ02 & J & capital J
& SP11 & . & full stop, period
\\ \hline
LK01 & k & small k
& SP12 & / & solidus
\\ \hline
LK02 & K & capital K
& SP13 & : & colon
\\ \hline
LL01 & l & small l
& SP14 & ; & semicolon
\\ \hline
LL02 & L & capital L
& SP15 & ? & question mark
\\ \hline
LM01 & m & small m
& SA01 & + & plus sign
\\ \hline
LM02 & M & capital M
& SA03 & $<$ & less-than sign
\\ \hline
LN01 & n & small n
& SA04 & = & equals sign
\\ \hline
LN02 & N & capital N
& SA05 & $>$ & greater-than sign
\\ \hline
LO01 & o & small o
& SM01 & \# & number sign
\\ \hline
LO02 & O & capital O
& SM02 & \% & percent sign
\\ \hline
LP01 & p & small p
& SM03 & \& & ampersand
\\ \hline
LP02 & P & capital P
& SM04 & * & asterisk
\\ \hline
LQ01 & q & small q
& SM05 & @ & commercial at
\\ \hline
LQ02 & Q & capital Q
& SM06 & [ & left square bracket
\\ \hline
LR01 & r & small r
& SM07 & $\backslash$ & reverse solidus
\\ \hline
LR02 & R & capital R
& SM08 & ] & right square bracket
\\ \hline
LS01 & s & small s
& SM11 & \{ & left curly bracket
\\ \hline
LS02 & S & capital S
& SM13 & $|$ & vertical bar
\\ \hline
LT01 & t & small t
& SM14 & \} & right curly bracket
\\ \hline
LT02 & T & capital T
& SD13 & \bq & grave accent
\\ \hline
LU01 & u & small u
& SD15 & $\hat{ }$ & circumflex accent
\\ \hline
LU02 & U & capital U
& SD19 & $\tilde{ }$ & tilde
\\ \hline
LV01 & v & small v
& & &
\\ \hline
LV02 & V & capital V
& & &
\\ \hline
LW01 & w & small w
& & &
\\ \hline
LW02 & W & capital W
& & &
\\ \hline
LX01 & x & small x
& & &
\\ \hline
LX02 & X & capital X
& & &
\\ \hline
LY01 & y & small y
& & &
\\ \hline
LY02 & Y & capital Y
& & &
\\ \hline
LZ01 & z & small z
& & &
\\ \hline
LZ02 & Z & capital Z
& & &
\\
\hline
\end{tabular} }
\end{prop}
The definition of semi-standard characters has been of minimum
practical use since implementations may or may not support any
of these characters. The essential feature is that, when
supported, they have a predictable treatment by the reader.
\begin{prop}
Remove all discussion of semi-standard characters.
Add that in implementations supporting control characters other than
\#$\backslash${\clkwd Newline}, the {\clkwd read} function
is required to treat those as
whitespace characters.
\end{prop}
%----------------------------------------------------------------------
\section{Hierarchy of Types}
Providing support for extensive character repertoires may
impact Common LISP implementation performance in terms
of space, time, or both.
\footnote{This does not apply to all implementations.
Unique hardware support and user community requirements need to
be taken into consideration.}
In particular, many existing
implementations support variants of the ISO 8859/1 standard.
Supporting large
repertoires argues for a multi-byte internal representation
for each character, even if an application primarily (or exclusively)
uses the ISO 8859/1 characters.
This proposal extends the definition of the character and string
type hierarchy to allow specialized subtypes
of character and string. An implementation is free to associate
compact internal representation tailored to each subtype.
The {\clkwd string} type specifier, when used for object
creation, for example in {\clkwd make-sequence},
is defined to mean the most general string subtype supported
by the implementation (similarly for the {\clkwd simple-string}
type specifier). This definition emphasizes portability
of existing Common LISP applications to international
character environments over performance. Applications emphasizing
efficiency of text processing in non-international environments
will require some modification to utilize subtypes with
compact internal representations.
It has been suggested that either a single type is
sufficient to support international characters,
or that a hierarchy of types could be used, in a manner
transparent to the user. A desire to provide flexibility which
encourages implementations to support international
characters without compromising application efficiency
led us to accept the need for more than one type.
We believe that these choices reflect a minimal
modification of this aspect of the type system, and that
exposing the types for string and character construction while
requiring uniform treatment for characters otherwise
is the most reasonable approach.
\subsection{Character Type}
\begin{prop}
Define {\clkwd base-character} as {\clkwd
(upgraded-array-element-type 'standard-char)}.
Characters of type {\clkwd base-character} are referred to as
{\em base characters}. Characters of type {\clkwd
(and character (not base-character))}
are referred to as {\em extended characters}.
\end{prop}
This establishes the relationship between the string encoding and
array upgrading strategies of the implementation and
the important character types.
An implementation may support additional subtypes of {\clkwd character}
which may or may not be supertypes of {\clkwd base-character}.
In addition, an implementation may define {\clkwd base-character}
as equivalent to {\clkwd character}.
The base characters are
distinguished in the following respects:
\begin{itemize}
\item
The standard characters are a subrepertoire of the base characters.
\item
The selection of base characters which are not standard characters
is implementation defined.
\item
Only members of the base character repertoire
can be elements of a base string.
\item
No upper bound is specified for the number of glyphs in the base
character repertoire--that
is implementation dependent. The lower bound is 96, the
number of standard characters defined for Common LISP.
\footnote{Or, in contrast, the base repertoire may include all
implementation supported characters.}
\end{itemize}
The distinction of base characters is largely a pragmatic
choice. It permits efficient handling of common situations, may
be privileged for host system I/O, and can serve as an
intermediate basis for portability, less general than the standard
characters, but possibly more useful across a narrower range of
implementations.
Many computers have some "base" character representation which
is a function of hardware instructions for dealing with characters,
as well as the organization of the file system. The base character
representation is likely to be the smallest transaction unit permitted
for text file and terminal I/O operations. On a system with a record
based I/O paradigm, the base character representation is likely to
be the smallest record quantum. On many computer systems,
this representation is a byte.
However,
the proposal emphasizes that whether a character is "base" to
Common LISP depends on the way that an implementation represents
strings, and not any other properties of the implementation or the
host operating system. Imagine two implementations, one of which
encodes all strings as 16-bit characters, and another which has
two kinds of strings: 8-bit strings and 16-bit strings. In the
first implementation, the {\clkwd base-character} is
{\clkwd character}: there's only one kind of string. In the
second implementation, the {\clkwd base-character} would be those
that could be stored in an 8-bit string, and it would be a proper
sub-type of {\clkwd character}.
\subsection{String Type}
\begin{prop}
The {\clkwd string} type
is defined as
a union type. More precisely, a string
is a specialized vector whose elements are of type
{\clkwd character} or a subtype of {\clkwd character}.
{\clkwd string} used as a type specifier for object creation
means {\clkwd (vector character)}.
\end{prop}
\begin{prop}
The following string
subtypes are
distinguished with standardized names.
\begin{itemize}
\item {\clkwd base-string} is equivalent to {\clkwd (vector
base-character)}.
Strings of type {\clkwd base-string} are referred to as {\em base
strings}. Strings which are not base strings are referred to
as {\em extended strings}.
\item {\clkwd general-string} is equivalent to {\clkwd (vector
character)}.
\item Both are valid as type specifiers that abbreviate.
\end{itemize}
During reader
construction of symbols, if all the characters
in the symbol's name are of type {\clkwd base-character},
then the name of the symbol may be stored as a base string.
Otherwise it will be stored as an extended string.
\end{prop}
\begin{prop}
Define {\clkwd simple-string} as a union type.
A simple
string is a specialized simple vector whose elements are of type
{\clkwd character} or a subtype of character.
{\clkwd simple-string} used as a type specifier for object creation
means {\clkwd (simple-array character ({\em size}))}.
\end{prop}
\begin{prop}
The following simple string
subtypes are
distinguished with standardized names:
\begin{itemize}
\item {\clkwd simple-base-string} is equivalent to {\clkwd
(simple-array base-character (*)). simple-base-string} is a subtype
of {\clkwd base-string}.
\item {\clkwd simple-general-string} is equivalent to {\clkwd
(simple-array character (*)). simple-general-string} is a subtype
of {\clkwd general-string}.
\item Both are valid as type specifiers that abbreviate.
\end{itemize}
\end{prop}
A base string is the most efficient string which can hold
the standard characters.
A {\clkwd general-string}
can contain any implementation supported base or extended characters,
in any mixture.
All Common LISP functions defined to operate on strings treat
base and extended strings uniformly with the following
caveat: for any function which inserts a character into a string, it
is an error to insert an extended character
into a base string.
\footnote{An implementation may, optionally, provide automatic
coercion to an extended string.}
An implementation may support string subtypes in addition
to {\clkwd base-string} and
{\clkwd general-string}.
For example, a hypothetical
implementation supporting Arabic and Cyrillic characters
might provide as extended characters:
\begin{itemize}
\item {\clkwd general-string} -- may contain Arabic, Cyrillic or
base characters in any mixture.
\item {\clkwd region-specialized-string} -- may contain installation
selected repertoire (Arabic/Cyrillic) or base characters in any
mixture.
\item {\clkwd base-string} -- may contain base characters
\end{itemize}
Though, clearly, portability of applications using
{\clkwd region-specialized-string} is limited, a performance
advantage might argue for its use.
\footnote{{\clkwd region-specialized-string} is used here for
illustration only; it is not being proposed as a standardized
string subtype.}
Alternatively,
an implementation
supporting a large base character repertoire
including, say, Japanese Kanji may define
{\clkwd base-character}
as equivalent to {\clkwd character}.
We expect that applications sensitive to the performance
of character handling in some host environments will
utilize the string subtypes to provide performance
improvement. Applications with emphasis on international
portability will likely utilize only {\clkwd general-string}s.
The base string type allows for more compact representation of strings
of base characters, which are likely to predominate in any system.
Note that in any particular implementation the base characters
need not be the
most compactly representable, since others might have
a smaller repertoire.
However, in most implementations base strings are
likely to be more space efficient than extended strings.
\begin{prop}
Extend the {\clkwd make-string} function to allow an
{\clkwd element-type} keyword argument:
\begin{itemize}
\item {\clkwd make-string} {\em size}
{\clkwd \&key :initial-element :element-type} [Function]
This returns a simple string of length {\em size}, each
of whose characters has been initialized to the
{\clkwd :initial-element} argument. If an {\clkwd :initial-element}
argument is not specified, then the string will be
initialized in an implementation-dependent way. The
{\clkwd :element-type} argument names the type of the elements
of the string; a string is constructed of the most specialized
type that can accommodate elements of the given type. If
{\clkwd :element-type} is omitted, the type {\clkwd character}
is the default.
\end{itemize}
\end{prop}
%----------------------------------------------------------------------
\section{Character Naming}
A Common LISP program should be able to name, compose and decompose
characters in a uniform, portable manner, independent of any
underlying representation. One possible composition is by
the pair $<$ coded character set standard, decimal representation $>$
\footnote{This syntax is for illustration only and is not being
proposed.}.
Thus, for example, one might compose the Latin 'A' with the pair
$<$ ISO8859/2-1987, 65 $>$,
$<$ ISO8859/6-1987, 65 $>$, or
$<$ ISO646-1983, 65 $>$, etc.. The difficulty here is two-fold.
First, there are several ways to compose the same character and
second, there may be multiple answers to
the question: {\em To what coded character set
does character object x belong?}\footnote{Even
worse, the answer might change yearly.}
The identical problems occur if the pair
$<$ character repertoire standard, decimal representation $>$ is used.
\footnote{Existing ISO repertoires seem to be defined exclusively
in the context of coded character sets and not as standards
in their own right.}
The concept of character registry is introduced by this proposal
to resolve the problem of character naming, composition and
decomposition.
Each character is universally defined by the
pair $<$ character registry name, character label $>$. For this
to be a portable definition, it must have a standard meaning.
Thus we propose the formation of an ISO Working Group to
define an international
{\em Character Registry Standard}.
At this writing there is no existing Character Registry Standard nor
ISO Working Group organized to define such a standard.
\footnote{It is the intention of X3 J13 to promote and adopt
an eventual ANSI or ISO Character Registry Standard. In particular, we
acknowledge that X3 J13 is {\em not} the appropriate forum to
define the standard. We believe
it is a required component of all programming languages
providing support for international characters.}
\begin{prop}
Common LISP character codes are composed from a character registry and
a character label. The convention by which a character label and
character registry compose a character code is implementation
dependent.
\end{prop}
The naming and content of the standard character registries
is left unspecified by this proposal.
\footnote{The only constraint is that character registries and
labels be named using only the Latin capital letters A-Z and
digits 0-9.}
Below are some candidate character registry names:
\begin{itemize}
\item Arabic
\item Armenian
\item Bopomofo
\item Control (meaning the collection of standard text communication
control codes)
\item Cyrillic
\item Georgian
\item Greek
\item Hangul
\item Hebrew
\item Hiragana
\item JapanesePunctuation
\item Kanji
\item Katakana
\item Latin
\item LatinPunctuation
\item Mathematical
\item Pattern
\item Phonetic
\item Technical
\end{itemize}
The list above is provided as a starting point for discussion
and is not intended to be representative
nor exhaustive. The Common LISP language definition does not
depend on these names nor any specific content (for example:
Where should the plus sign appear?). It is application
programs which require a reliable definition of the
registry names and their constituents. The Common LISP language
definition imposes the framework for constructing and manipulating
character objects.
\begin{prop}
Standardized Character Registries are fixed;
an implementation may not extend a standard registry's
constituent set of characters beyond the
standard definition.
An implementation may provide support for all or part of any
character registry
and may provide new character registries which include characters
having unique semantics (i.e. not defined in any standard
character registry).
Implementation registries must be uniquely
named using only Latin capital letters A-Z and digits 0-9.
An implementation must document the registries it supports.
For each registry supported the documentation must include
at least the following:
\begin{itemize}
\item Character Labels,
Glyphs, and Descriptions. Character labels must be uniquely
named using only Latin capital letters A-Z and digits 0-9.
\item Reader Canonicalization.
\footnote{Any mechanisms by which the {\clkwd read} function treats
distinct characters as equivalent.}
\item Effect of character predicates. In particular,
\begin{itemize}
\item {\clkwd alpha-char-p}
\item {\clkwd lower-case-p}
\item {\clkwd upper-case-p}
\item {\clkwd both-case-p}
\item {\clkwd graphic-char-p}
\item {\clkwd alphanumericp}
\end{itemize}
\item Interaction with File I/O. In particular, the
coded character sets
\footnote{For example, ISO8859/1-1987.} and
external encoding schemes
supported are documented.
\end{itemize}
\end{prop}
We introduce new functions to
compose and decompose character objects. We also extend the
{\clkwd characterp} predicate to
support testing
membership of a character in a given character repertoire.
\footnote{
For example,
testing membership in the Japanese Katakana character repertoire.
}
A global variable {\clkwd *all-character-registry-names*}
is added to
allow application determination of
implementation supported character registries.
\begin{prop}
Add the type specifier and (modified) type predicate:
\begin{itemize}
\item {\clkwd (character {\em repertoire})}
This denotes a character type specialized to members of the
specified repertoire. {\em Repertoire} may be {\clkwd :base}
or {\clkwd :standard} or any supported character repertoire
name (a keyword symbol), or a list of names.
{\clkwd (character :base)} is equivalent to {\clkwd base-character}
and
{\clkwd (character :standard)} is equivalent to {\clkwd standard-char}
\item {\clkwd (characterp {\em object} \&optional
{\em repertoire})}
If {\em repertoire} is omitted, {\clkwd characterp} is true if
{\em object} is a character object, and otherwise is false. If
a {\em repertoire} argument is specified, {\clkwd characterp}
is true if {\em object} is a character object and a member
of the specified repertoire, and otherwise is false. {\em Repertoire}
may be any supported character repertoire name (a keyword symbol)
or the names {\clkwd :base} or {\clkwd :standard}.
{\clkwd (characterp x :standard)} is equivalent to
{\clkwd (standard-char-p x)}.
{\clkwd (characterp x :base)} is true if x is a member of the
base character repertoire.
\end{itemize}
\end{prop}
\begin{prop}
Add the following variable and functions:
\begin{itemize}
\item {\clkwd *all-character-registry-names*} {\em [Variable]}
The value of {\clkwd *all-character-registry-names*} is a list
of all character repertoire names (keyword symbols) supported by
the implementation.
\item {\clkwd char-label} {\em char [Function]}
{\clkwd char-label} returns a string representing the character
label of {\em char}. It is an error if the argument is
not a character object.
\item {\clkwd char-registry-name} {\em char [Function]}
{\clkwd char-registry-name} returns a string representing the character
registry to which {\em char} belongs. It is an error if the
argument is not a character object.
\item {\clkwd find-char} {\em registry label [Function]}
{\clkwd find-char} returns a character object. The arguments
{\em registry} and {\em label} are names (keyword symbols) of
a character registry and label. {\em label} uniquely
identifies a character within the character registry named
{\em registry}. If the implementation does not support the
specified character, {\clkwd nil} is returned.
\end{itemize}
\end{prop}
\begin{prop}
Character
names accepted and constructed by {\clkwd char-name, name-char,
and read} are extended to include character registry names of
the form {\em registry:label}.
\end{prop}
%----------------------------------------------------------------------
\section{Streams and System I/O}
A lot of the work of ensuring that a
Common LISP implementation operates correctly in a
multiple coded character set environment must be performed by
the I/O interface.
The system I/O interface, abstracted in
Common LISP as streams, is responsible
for ensuring that text input from outside LISP is properly mapped
into character objects internally, and that the inverse mapping
is performed on output. It is beyond the scope of a language
definition to specify the details of this operation, but options
are specified which allow runtime indication from the user as to
what coded character sets a stream uses, and how the mappings
should be done. It is expected that implementations will provide
reasonable defaults and invocation options to accommodate desired use
at an installation.
There are often multiple
coded character sets supportable on a
computer, through the use of special display and entry hardware, which
are varying interpretations of the basic system character
representation. For example, ISO 8859/1 and ISO 6937/2 are two
different interpretations of the same 1-byte code representations.
Many countries have their own glyph-to-code mappings for 1-byte
character codes addressing the special requirements of national
languages. Differentiating between these, without reference to
display hardware, is a matter of convention, since they all use the
same set of code representations. When a single byte is not enough,
two or more bytes are sometimes used for character encoding. This
makes character handling even more difficult on machines where the
natural representation size is a byte, since not only is the semantic
value of a character code a matter of convention, which may vary
within the same computing system, but so is the identification of a
set of bits as a complete character code.
Given that multiple coded character sets exist, it is useful
to provide portable mechanisms based on their definitions.
\begin{prop}
Add the following functions:
\begin{itemize}
\item {\clkwd char-external-code} {\em char name [Function]}
{\clkwd char-external-code} returns the non-negative integer
representing the encoding of the character {\em char} in the
coded character set named by {\em name}, a keyword symbol. If
the implementation does not support the specified coded
character set, {\clkwd nil} is returned. If the named
coded character set does not contain the character,
{\clkwd nil} is returned.
\item {\clkwd find-external-char} {\em name index [Function]}
{\clkwd find-external-char} returns a character object.
The argument {\em index} is a non-negative integer
representing the encoding of a character in the
coded character set named by {\em name}, a keyword symbol. If
the implementation does not support the specified coded
character set, {\clkwd nil} is returned. If the named
coded character set does not contain the character,
{\clkwd nil} is returned.
\end{itemize}
\end{prop}
An implementation supporting multiple coded character sets
must allow for the external
representation of characters to be separately (and perhaps
multiply) specified to {\clkwd open},
since there can be circumstances under
which more than one external representation for characters
is in use, or more than one coded character set
is mixed together in an
external representation convention.
Which coded character sets and encoding schemes
are supported by the overall computing system and the
details of the mapping of glyphs to characters
to character codes are
left unspecified by Common LISP.
\begin{prop}
Add the additional keyword argument to {\clkwd open}:
\begin{itemize}
\item {\clkwd :external-code}
which
specifies a name, or list of names (keyword symbols)
indicating an implementation recognized scheme for
representing 1 or more coded character sets with non-homogeneous codes.
The default value is {\clkwd :default} and is
implementation defined but must include the
base characters.
As many coded character set names must be provided as the
implementation requires for that external coding convention.
Coded character set names must
include the full reference number and approval year. For example,
:ISO8859P1V1987 and :ISO6937P2V1983.
All implementation recognized schemes are formed from
the Latin uppercase A-Z and digit 0-9 characters.
\end{itemize}
This argument is provided for input, output, and
bidirectional streams.
It is an error to try to write a character other than a
member of the specified coded character sets
to a stream. (This excludes the
\#$\backslash${\clkwd Newline} character.
Implementations must provide appropriate line division behavior
for all character streams.)
\end{prop}
The existing default for the {\clkwd :element-type} argument of
{\clkwd open} is {\clkwd string-char}. This is no longer appropriate
given the diminished use of {\clkwd string-char} within the
standard specification.
\begin{prop}
Modify the {\clkwd :element-type} argument to {\clkwd open} as follows:
\begin{itemize}
\item Add {\clkwd base-character} as a valid type.
\item Remove {\clkwd string-char} as a valid type.
\end{itemize}
\end{prop}
The following alternative is consistent with the general
premise that portability is emphasized over efficiency.
\begin{prop} (Alternative A)
The default for the {\clkwd :element-type} argument of {\clkwd open}
is {\clkwd character}.
\end{prop}
The following alternative (B), allows implementations to match
the behavior of {\clkwd open} to the expected behavior of
their file systems.
\begin{prop} (Alternative B)
The default for the {\clkwd :element-type} argument of {\clkwd open}
is implementation defined as either {\clkwd base-character}
or {\clkwd character}.
\end{prop}
\begin{prop}
Modify the following functions:
\begin{itemize}
\item {\clkwd with-output-to-string} if no string argument is
provided, produces a stream that accepts all characters and returns
a string of the most specialized type
that accommodates the characters that were actually output.
\item {\clkwd make-string-output-stream}
produces a stream that accepts all characters and returns
(via {\clkwd get-output-stream-string})
a string of the most specialized type
that accommodates the characters that were actually output.
\end{itemize}
\end{prop}
In addition to supporting conversion at the system interface, the
language must allow user programs to determine how much space data
objects will require when output in whichever external representations
are available.
This function is necessary
to determine if strings can be written to fixed length
fields in databases. Note that this
function does not
address the problem of calculating
screen width of strings printed in proportional fonts.
\begin{prop}
Add the following function:
\begin{itemize}
\item {\clkwd string-encoded-length} {\em object}
{\clkwd \&optional} {\em output-stream} [Function]
{\clkwd string-encoded-length} returns the number of
implementation defined units required for the object on the
output stream. If not applicable to the output stream, the
function returns {\clkwd nil}. This number
corresponds to the current state of the stream and may change if
there has been intervening output. If the
output stream is not specified {\clkwd *standard-output*} is
the default.
\end{itemize}
\end{prop}
%----------------------------------------------------------------------
\section{Miscellaneous}
In the process of creating this document, some comments were found
within CLtL which seem appropriate to modify independently of
the other proposals mentioned previously. For each, we identify
the existing statement of CLtL and the recommended change.
%----------------------------------------------------------------------
%----------------------------------------------------------------------
\newcommand{\edithead}{\begin{tabular}{l p{3.95in}}
\multicolumn{2}{l} }
\newcommand{\csdag}{\bf$\Rightarrow$\ddag}
\newcommand{\editstart}{}
\newcommand{\editend}{\\ & \end{tabular}}
%----------------------------------------------------------------------
%----------------------------------------------------------------------
%----------------------------------------------------------------------
\begin{prop}
\edithead {\csdag (p12) Chapter 2 Data Types}
\editstart
\\ \bf replace &
\cltxt
provides for a
rich character set, including ways to represent characters of various
type styles.
\\ \bf with &
\cltxt
provides support for international language characters as well
as characters used in specialized arenas, eg. mathematics.
\editend
\end{prop}
\begin{prop}
\edithead {\csdag (p25) Chapter 2 Symbols}
\editstart
\\ \bf replace &
\cltxt
A symbol may have uppercase letters, lowercase letters, or
both in its print name.
\\ \bf with &
\cltxt
A symbol may have characters from any supported character
repertoire (except control characters) in its print name.
\editend
\end{prop}
\begin{prop}
\edithead {\csdag (p163) Chapter 10 Symbols}
\editstart
\\ \bf replace &
\cltxt
It is ordinarily not permitted to alter a symbol's print name.
\\ \bf with &
\cltxt
It is an error to alter a symbol's print name.
\editend
\end{prop}
\begin{prop}
\edithead {\csdag (p168) Chapter 10 The Print Name}
\editstart
\\ \bf replace &
\cltxt
It is an extremely bad idea to modify a string being used
as the print name of a symbol.
\\ \bf with &
\cltxt
It is an error to modify a string being used
as the print name of a symbol.
\editend
\end{prop}
\begin{prop}
\edithead {\csdag (p249,make-sequence) Chapter 14 Simple Sequence
Functions}
\editstart
\\ \bf append &
\cltxt
If type {\clkwd string} is specified, the result is
equivalent to {\clkwd make-string}.
\editend
\end{prop}
%----------------------------------------------------------------------
%----------------------------------------------------------------------
%----------------------------------------------------------------------
\begin{thebibliography}{wwwwwwww 99}
\bibitem[Ida87]{ida87} M. Ida, et al.,
{\em
JEIDA Common LISP Committee Proposal on Embedding Multi-Byte Characters
},
ANSI X3J13 document 87-022, (1987).
\bibitem[ISO 646]{iso646} ISO,
{\em
Information processing -- ISO 7-bit coded character set
for information interchange
},
ISO (1983).
\bibitem[ISO 4873]{iso4873} ISO,
{\em
Information processing -- ISO 8-bit code for information
interchange -- Structure and rules for implementation
},
ISO (1986).
\bibitem[ISO 6937/1]{iso6937/1} ISO,
{\em
Information processing -- Coded character sets for text
communication -- Part 1: General introduction
},
ISO (1983).
\bibitem[ISO 6937/2]{iso6937/2} ISO,
{\em
Information processing -- Coded character sets for text
communication -- Part 2: Latin alphabetic and non-alphabetic
graphic characters
},
ISO (1983).
\bibitem[ISO 8859/1]{iso8859/1} ISO,
{\em
Information processing -- 8-bit single-byte coded
graphic character sets -- Part 1: Latin alphabet No. 1
},
ISO (1987).
\bibitem[ISO 8859/2]{iso8859/2} ISO,
{\em
Information processing -- 8-bit single-byte coded
graphic character sets -- Part 2: Latin alphabet No. 2
},
ISO (1987).
\bibitem[ISO 8859/6]{iso8859/6} ISO,
{\em
Information processing -- 8-bit single-byte coded
graphic character sets -- Part 6: Latin/Arabic alphabet
},
ISO (1987).
\bibitem[ISO 8859/7]{iso8859/7} ISO,
{\em
Information processing -- 8-bit single-byte coded
graphic character sets -- Part 7: Latin/Greek alphabet
},
ISO (1987).
\bibitem[Kerns87]{kerns87} R. Kerns,
{\em
Extended Characters in Common LISP
},
X3J13 Character Subcommittee document, Symbolics Inc (1987).
\bibitem[Kurokawa88]{kurokawa88} T. Kurokawa, et al.,
{\em
Technical Issues on International Character Set Handling in Lisp
},
ISO/IEC SC22 WG16 document N33, (1988).
\bibitem[Linden87]{linden87} T. Linden,
{\em
Common LISP - Proposed Extensions for International Character Set
Handling
},
Version 01.11.87, IBM Corporation (1987).
\bibitem[Steele84]{steele84} G. Steele Jr.,
{\em
Common LISP: the Language
},
Digital Press (1984).
\bibitem[Xerox87]{xerox87} Xerox,
{\em
Character Code Standard, Xerox System Integration Standard
},
Xerox Corp. (1987).
\end{thebibliography}
\end{document} % End of document.
∂23-Mar-89 0702 X3J13-mailer Re: 20 March cs proposal
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 07:02:51 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA01052; Thu, 23 Mar 89 08:02:48 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12413; Thu, 23 Mar 89 08:02:45 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903231502.AA12413@defun.utah.edu>
Date: Thu, 23 Mar 89 08:02:44 MST
Subject: Re: 20 March cs proposal
To: Thom Linden <baggins@IBM.com>
Cc: Common Lisp mailing <x3j13@sail.stanford.edu>
In-Reply-To: Thom Linden <baggins@IBM.com>, Wed, 22 Mar 89 15:01:01 PST
> Sandra, if possible please put a DVI file out on cs.utah.edu again)
Done. It's in the same place as before, ~ftp/pub/cl-cs-proposal.dvi.
-Sandra
-------
∂23-Mar-89 0903 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89 09:03:25 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563608; Thu 23-Mar-89 12:03:12 EST
Date: Thu, 23 Mar 89 12:03 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
To: x3j13@SAIL.STANFORD.EDU
In-Reply-To: <8903220438.AA22664@challenger>
Message-ID: <19890323170307.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
It's not very important to me whether we call it a clarification
or a change. What's more important is that we agree on a definition
of simple-array and that we get this issue behind us so we can move
on and finish this standard, so we can all go home.
The fundamental question, I think, is whether simple-array is a
conceptual type or a representation type. I had assumed based on the
discussions that lead to the writing of CLtL, and on the lack of any
contradiction, that everyone agreed that it is a representation type and
all we had to do was state the details more clearly. Apparently I was
mistaken.
Let me explain what I mean by those terms. A conceptual type is one
that the programmer of a portable program thinks of as conceptually
distinct data. For example, RATIO is a conceptual type. No one thinks
a RATIO is another kind of CONS, and probably no one thinks a RATIO
is another kind of FLOAT. All implementations agree on which objects
are of type RATIO and which are not.
A representation type is one that is not a conceptually distinct form of
data. We have such types in the language in order to expose enough of
the implementation-dependent representation to permit user programs to
be specialized for one representation, so we can compile better code.
Representation types are a compromise between portability and
efficiency, and as such their definition is generally
implementation-dependent. We define just enough about a representation
type so a programmer can figure out whether to use it, but we do not
constrain all implementations to use the same representation. A
representation type is always a subtype of a conceptual type and
includes some, but not necessarily all, members of that conceptual type
that are implemented in some particularly efficient way. A good example
of a representation type is FIXNUM. Not all implementations agree on
which objects are of type FIXNUM. However, we have defined FIXNUM
closely enough (it includes a certain range of the integers, as well as
possibly some other integers) to allow a programmer to decide whether a
given variable in a given program can or cannot be declared FIXNUM. We
specify some integers that are guaranteed to be FIXNUM, but we do not
specify any integers that are guaranteed never to be FIXNUM in any
implementation.
Back to SIMPLE-ARRAY. If SIMPLE-ARRAY is a conceptual type, then an
array is a SIMPLE-ARRAY if-and-only-if it meets certain criteria, and
all implementations must agree on exactly which objects are of type
SIMPLE-ARRAY. Programmers would think of SIMPLE-ARRAYs as distinctly
different from ordinary arrays, and when programming would frequently
ask themselves "should I use a SIMPLE-ARRAY here or a regular ARRAY"
even when not thinking at all about efficiency or optimization. They
would write their program differently depending on whether they used
a SIMPLE-ARRAY or a regular ARRAY, just as they would write their
program differently depending on whether they used a LIST or a VECTOR.
On the other hand, if SIMPLE-ARRAY is a representation type, then an
array is a SIMPLE-ARRAY if-and-only-if it is implemented with a
simpler, more efficient representation than regular arrays. An array is
a SIMPLE-ARRAY if, but not only-if, it meets certain criteria. In other
words we define a common intersection of the SIMPLE-ARRAY types of
all implementations, but we allow implementations to expand their
SIMPLE-ARRAY types to include other arrays, as appropriate to their
machine, just like FIXNUM, BASE-CHARACTER, and (ARRAY (UNSIGNED-BYTE 4)).
Programmers would only ask themselves "should this be a SIMPLE-ARRAY"
when thinking about efficiency and optimization.
I believe SIMPLE-ARRAY is a representation type because, as a
programmer, I don't think of it as conceptually different from an
ordinary array, and because, as a historian, I know that SIMPLE-ARRAY
was added to Common Lisp in 1982, and attained its current form in 1983,
in order to address the concern of many implementors that using the
fully general representation for all arrays would be too slow, as a
result of the large number of array features in Common Lisp. The idea
was to permit use of a simpler, streamlined representation for some
arrays, and to make that representation available in TYPE declarations
so the compiler could optimize AREF on it.
To proceed, I think we should first reach a concensus on whether
SIMPLE-ARRAY is a conceptual or a representation type. Once we have
done that, we will have a framework within which to decide the specific
details of its behavior.
∂23-Mar-89 1504 X3J13-mailer **DRAFT** Issue: PATHNAME-CANONICAL-TYPE (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89 12:07:40 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 563815; 23 Mar 89 15:06:56 EST
Date: Thu, 23 Mar 89 15:06 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-CANONICAL-TYPE (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323150638.0.KMP@BOBOLINK.SCRC.Symbolics.COM>
>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<
Bring your comments to the meeting.
See summary of CL-Cleanup discussion at end of message.
-kmp
-----
Issue: PATHNAME-CANONICAL-TYPE
References: MAKE-PATHNAME (p416)
Category: ADDITION
Edit history: 07-Jul-88, Version 1 by Pitman
Status: For Internal Discussion
Related-Issues: PATHNAME-COMPONENT-CASE
Problem Description:
The pathame-type of ``Lisp'' and ``Compiled Lisp'' files vary widely from
implementation to implementation.
"LSP" is common on Vax VMS. "lisp" is generally used for the Symbolics
file system. "l" and "lisp" are common on Unix. Some Lisp implementations
use customized extensions such as "cl" or even "jcl" (eg, for "Joe's CL").
It would be useful to probe the existence of either a source or a binary
file, but that cannot currently be done portably. Furthermore, it would be
useful to create certain standard kinds of files in a system-independent
fashion.
A common desire, for example, is to do
(DEFUN FILE-NEEDS-TO-BE-COMPILED (FILE)
(LET ((SOURCE (PROBE-FILE
(MERGE-PATHNAMES FILE (MAKE-PATHNAME :TYPE ???))))
(BINARY (PROBE-FILE
(MERGE-PATHNAMES FILE (MAKE-PATHNAME :TYPE ???)))))
... (FILE-WRITE-DATE SOURCE) ... (FILE-WRITE-DATE BINARY) ...))
The problem is that there's nothing portable to put in the ??? positions.
Indeed, depending on the host (ie, file system) of the pathname, the
type might need to differ even in the same Lisp implementation. For example,
Symbolics Genera stores its source files in names like "foo.l" on Unix,
"FOO.LSP" on VMS, etc.
Proposal (PATHNAME-CANONICAL-TYPE:NEW-CONCEPT):
In addition to the normal strings and keywords currently allowed as fillers
of the TYPE field of a pathname, allow other keywords which designate
``canonical types''.
A canonical type is translated to a real type by MAKE-PATHNAME so that the
(PATHNAME-TYPE (MAKE-PATHNAME :TYPE canonical-type)) is a string.
Introduce a new function PATHNAME-CANONICAL-TYPE which returns the canonical
type of an argument pathname, or the type if there is no canonical type.
For example,
(PATHNAME-CANONICAL-TYPE (MAKE-PATHNAME :TYPE :LISP)) => :LISP
[This information may be explicitly represented as an additional slot, or
computed on demand using a lookup table, as the implementor prefers.]
Define the following standard types:
:LISP ``Lisp'' (source) file
:BIN ``Compiled Lisp'' (object) file
Permit implementations to extend the set of canonical type names.
Test Case:
(PATHNAME-TYPE (MAKE-PATHNAME :TYPE :LISP))
=> "LSP" ;Typically, on VMS
=> "l" or "lisp" ;Typically, on Unix
=> "L" or "LISP" ;Typically, on Unix
; (assuming PATHNAME-COMPONENT-CASE:CANONICALIZE adopted)
..etc.
(PATHNAME-TYPE (MAKE-PATHNAME :TYPE :BIN))
=> "FAS" ;eg, VAXLISP
=> "BIN" ;eg, Symbolics file system
...etc.
(PATHNAME-CANONICAL-TYPE (MAKE-PATHNAME :TYPE :LISP)) => :LISP
(PATHNAME-CANONICAL-TYPE (MAKE-PATHNAME :TYPE "LSP"))
=> :LISP ;eg, VAXLISP
=> "LSP" ;eg, Unix
Rationale:
This is a useful subset of the functionality already available in
at least one implementation.
Current Practice:
Symbolics Genera implements this proposal.
Cost to Implementors:
The cost of implementing these proposed features is very slightly.
MAKE-PATHNAME would have to change to coerce its :TYPE argument in implementations
where it does not do so already. PATHNAME-CANONICAL-TYPE can be implemented as a
fairly straightforward lookup.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
It would continue to be hard to portably name files when their types
differed from file system to file system.
Benefits:
The cost of non-adoption would be avoided.
Aesthetics:
Some programs would be able to abstract away from the particulars of the host
file system entirely. Some people believe this would be a definite improvement
in aesthetics.
Discussion:
Note that different Lisp implementations which share the same file system,
need not and perhaps should not agree on the same type string for the
canonical type :BIN. That is, if I store source files on VAX VMS and compile
them both for use under Symbolics Genera and VAXLISP, then it is both
appropriate and useful that VAXLISP :BIN files be named "something.FAS"
and Genera :BIN files be named "something.BIN" since then they wouldn't
clobber each other.
Pitman supports PATHNAME-CANONICAL-TYPE:NEW-CONCEPT.
-------
Summary of discussion on CL-Cleanup:
GZ suggested :COMPILED-LISP was suggested as a better name than :BIN.
Masinter thought :SOURCE-LISP might be better than :LISP. Either of these
would be gratuitously incompatible with Symbolics Genera, which already
implements canonical types, but otherwise not technically unreasonable
and probably something we should discuss.
Sandra Loosemore offered the following revealing piece of code from her
work and asked why we couldn't just do this.
(defvar *binary-file-type*
#+Symbolics (make-pathname :type "bin")
#+(and dec common vax (not ultrix)) (make-pathname :type "FAS")
#+(and dec common vax ultrix) (make-pathname :type "fas")
#+pcls (make-pathname :type "b")
#+KCL (make-pathname :type "o")
#+Xerox (make-pathname :type "dfasl")
#+(and Lucid MC68000) (make-pathname :type "lbin")
#+(and Lucid VAX VMS) (make-pathname :type "vbin")
#+excl (make-pathname :type "fasl")
#+system::cmu (make-pathname :type "sfasl")
#+PRIME (make-pathname :type "pbin")
#+HP (make-pathname :type "b")
#+TI (make-pathname :type "xfasl")
"The default file type for compiled files.")
The reason is that some implementations (e.g., Symbolics) deal with more
than one file system type -- and properly the information varies with the
file system type, not with the implementations. [Since most implementations
have only one associated file system type, this may not be obvious, but it's
quite obvious on a Symbolics machine that you vary the extension name based
on the host file system requirements.]
Moon suggested a compromise where *compile-file-output-type* (his name
for Sandra's *binary-file-type*) existed but could be either a canonical
type or a physical type.
Masinter worries about the PATHNAME-CANONICAL-TYPE part of the proposal
being forced to be heuristic in some cases. [Will any alternative be any
less heuristic? -kmp]
Moon wanted the following example to be guaranteed to work:
(PATHNAME-CANONICAL-TYPE (PATHNAME "foo.lisp")) => :LISP
where of course the string is implementation-dependent. That is,
PATHNAME-CANONICAL-TYPE must produce a canonical type even when the
pathname was not constructed from a canonical type, but instead came
from user typein, the TRUENAME function, the DIRECTORY function,
or some similar source, when the pathname's type is one that a
canonical type maps into.
Moon also thought it would be nice to have a facility for users
(in addition to implementations) to extend the set of canonical type
names, since users may well have their own types of files. However,
he admitted that the difficulty is that in any system that supports
multiple file systems, it has to be complex enough to allow
specification of separate mappings for each file system, which in
turn requires a way to name file system types. [At this point, we
probably don't have time left in our schedule to produce such a
facility. -kmp]
∂23-Mar-89 1503 X3J13-mailer **DRAFT** Issue: PATHNAME-EXTENSIONS (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89 11:47:13 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563798; Thu 23-Mar-89 14:47:01 EST
Date: Thu, 23 Mar 89 14:46 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-EXTENSIONS (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323144641.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
>>> PLEASE DO -NOT- REPLY TO THIS MESSAGE <<<
It's probably so late that no one will read what you have to say
anyway. Ponder it and bring your comments to the meeting.
Summary of debate on CL-Cleanup follows at end.
-kmp
-----
Issue: PATHNAME-EXTENSIONS
Forum: Cleanup
References: Pathnames (pp410-413)
Category: ADDITION
Edit history: 28-Dec-88, Version 1 by Pitman
Status: For Internal Discussion
Problem Description:
CLtL is quite strict about what may and may not be in any kind of
pathname, leaving implementors up against a brick wall when an
idiosyncratic extension is necessary to uniquely and usefully
represent all files in a particular file system which may not have
been completely anticipated by the Common Lisp designers.
Proposal (PATHNAME-EXTENSIONS:NEW-PREDICATE):
Introduce a function COMMON-PATHNAME-P, described as follows:
COMMON-PATHNAME-P pathname [Function]
Returns true if its argument satisfies the Common Lisp
pathname model, and false otherwise. If the argument is
not a pathname, an error of type TYPE-ERROR is signalled.
Clarify that COMMON-PATHNAME-P considers a pathname's host field
to fit the Common Lisp pathname model if the filler of the host
field is a string (naming a host), and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's device to fit
the Common Lisp pathname model if it is a string naming a device,
or NIL, or :WILD[, or, if issue PATHNAME-COMPONENT-UNSPECIFIC
passes, is :UNSPECIFIC], and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's directory
field to fit the Common Lisp pathname model if the filler of the
directory field is NIL, or :WILD, or a string[, or, if issue
PATHNAME-SUBDIRECTORY-LIST passes, is a list described as valid
by that proposal][, or, if issue PATHNAME-COMPONENT-UNSPECIFIC
passes, is :UNSPECIFIC], and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's name to
fit the Common Lisp pathname model if it is a string, or NIL,
or :WILD, and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's type to
fit the Common Lisp pathname model if it is a string, or :WILD,
or NIL[, or, if issue PATHNAME-COMPONENT-UNSPECIFIC passes, is
:UNSPECIFIC], and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's version to
fit the Common Lisp pathname model if it is a positive integer,
:WILD, or NIL, or :NEWEST[, or, if issue PATHNAME-COMPONENT-UNSPECIFIC
passes, is :UNSPECIFIC], and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname to be outside
the Common Lisp model if it contains special syntax or purpose
which is not readily apparent to Common Lisp programs. For example,
if a character like "*" or "~" has special meaning to the file
system, then strings like "F*X" or "~FOO" which exploit that syntax
are not considered to "fit the model". [Note that if issue
PATHNAME-WILD passes, WILD-PATHNAME-P might still be true of
some pathnames that were not COMMON-PATHNAME-P.]
Test Case:
;; On Unix...
(common-pathname-p (make-pathname :name "f*x"))
=> nil
;; On Tops-20...
(common-pathname-p (make-pathname :name "FOO" :version -1))
;; On VMS...
(common-pathname-p (parse-namestring "x::y::z::w::[joe]a.b"))
=> nil
;; Normally
(common-pathname-p (make-pathname :name "FOO" :version :wild))
=> t
(common-pathname-p (make-pathname :name "FOO" :version 17))
=> t
Rationale:
The purpose of COMMON-PATHNAME-P is not to detect pathnames which
are not valid. Indeed, no Common Lisp function requires that its
argument satisfy this test; it is assumed that functions such as
OPEN and MERGE-PATHNAMES will recognize and deal appropriately with
whatever special pathname syntax is appropriate to the host operating
system. Rather, the purpose of COMMON-PATHNAME-P is to help Common
Lisp programs which try to pick apart a pathname and perform some
sort of simulated merging on the basis of the simple pathname model
put forth by Common Lisp, so that such programs can detect situations
which are beyond their capabilities.
Current Practice:
Probably nobody implements this.
Cost to Implementors:
Small. The program is fairly straightforward. It could almost be
written as a portable library if it weren't for detecting special
characters that have some special syntax.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Some idiosyncratic system syntax would be hard to detect.
Making extensions to the pathname system in a way that Common Lisp
users would not be forced to trip over would be more difficult.
Benefits:
Some ad-hoc user code which tries to do the same thing could be
eliminated. Portable programs which must prompt for native pathname
syntax, and deal with the result of having parsed it could be more
robust.
Making idiosyncratic extensions to the pathname system would be much
less prone to cause problem for portable programs which used this
facility.
The presence of this operator could someday ease the transition
into a future, incompatible pathname system.
Aesthetics:
Probably improves aesthetics slightly by giving people who want to
reject extended pathnames a more reliable way of weeding them out.
Discussion:
The COMMON data type was probably intended to have this same purpose.
Unfortunately, since no one ever really said specifically enough what
was in COMMON or not, and why, it never really caught on. Hopefully
this proposal is definite enough on such issues to not be useless.
Pitman thinks this is probably a good idea.
------- Summary of debate -------
Discussion on CL-Cleanup centered around two issues:
- Is this really needed? What could it be used for?
I suggested following program as an illustration:
(DEFUN TRANSLATE-LOGICAL-PATHNAME (LPATHNAME)
(MULTIPLE-VALUE-BIND (LHOST LDEVICE LDIR LNAME LTYPE LVERSION)
(PARSE-LOGICAL-PATHNAME LPATHNAME)
(MULTIPLE-VALUE-BIND (PHOST PDEVICE PDIR PNAME PTYPE PVERSION)
(TRANSLATE-PATHNAME-COMPONENTS LHOST LDEVICE LDIR LNAME LTYPE LVERSION)
(LET ((PHYSICAL-PATHNAME (MAKE-PATHNAME :HOST PHOST ...)))
(UNLESS (COMMON-PATHNAME-P PHYSICAL-PATHNAME)
(CERROR "Use ~*~A anyway."
"The result of translating pathname ~A to a physical pathname~
~%resulted in a valid physical pathname, ~A,~
~%but that pathname has special meaning to host ~A which may~
~%not have been what was intended."
LPATHNAME PHYSICAL-PATHNAME PHOST))))))
Also, recently there has been concern (e.g., in issue
PATHNAME-SUBDIRECTORY-LIST) about requirements for conformance
precluding interesting extensions that particular implementations
might want to experiment with. This would provide a way for portable
programs to guard against such `creative' extensions.
- Isn't this something users could write?
The answer is no. What is a non-portable pathname cannot be portably
detected. e.g., the fact that "*" or "~" or "{" or whatever is magic
in some filename syntax and not in another is (almost by definition) not
something that is portably detectable. Portable programs can just decide
to limit themselves to the least common denominator (e.g., refusing to let
you type in any pathname to a prompt for pathname if it has an `scary
looking' character in it), but this provides a way of being both a little
more robust and a little more tolerant.
For those who are curious, I'm not adamant about this proposal. I just
want it to be available as an option in case it eases the discussion on
other issues.
-kmp
∂23-Mar-89 1503 X3J13-mailer issue CLOS-MACRO-COMPILATION, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 11:35:38 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA10107; Thu, 23 Mar 89 12:35:34 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12651; Thu, 23 Mar 89 12:35:31 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903231935.AA12651@defun.utah.edu>
Date: Thu, 23 Mar 89 12:35:30 MST
Subject: issue CLOS-MACRO-COMPILATION, version 3
To: x3j13@sail.stanford.edu
This is a revised version of the writeup that was sent out last week.
The major change is to the language about error situations under
DEFMETHOD.
Forum: Compiler
Issue: CLOS-MACRO-COMPILATION
References: CLOS chapters 1 & 2 (88-002R)
CLOS chapter 3 (89-003)
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CLARIFICATION
Edit History: V1, 10 Mar 1989, Sandra Loosemore
V2, 13 Mar 1989, Sandra Loosemore
V3, 21 Mar 1989, Sandra Loosemore (fix error language)
Status: Ready for release
Problem Description:
Do the CLOS defining macros (DEFCLASS, DEFMETHOD, DEFGENERIC, and
DEFINE-METHOD-COMBINATION) have compile-time side-effects similar
to those for DEFSTRUCT or DEFMACRO?
A part of the problem is that we do not currently have a full
understanding of all the issues involved. In particular, work on
defining the CLOS meta-object protocol is still in progress. The goal
of this proposal is to say enough about the behavior of these macros
in the standard so that users can use them portably in compiled code,
but to leave as much of the behavior as possible unspecified to avoid
placing undue restrictions on the meta-object protocol.
There are two proposals, MINIMAL and NOT-SO-MINIMAL.
Proposal CLOS-MACRO-COMPILATION:MINIMAL:
State that top-level calls to the CLOS defining macros have the
following compile-time side-effects. Any other compile-time behavior
is explicitly left unspecified.
DEFCLASS:
* The class name becomes a type specifier which may appear in
subsequent type declarations.
* The class name can be used to name a superclass in a subsequent
DEFCLASS.
* The class name can be used as a specializer in a subsequent
DEFMETHOD.
DEFGENERIC:
* The generic function can be referenced in a subsequent DEFMETHOD.
* The generic function is not callable at compile-time.
DEFMETHOD:
* The method is not callable at compile-time. If there is a generic
function with the same name at compile-time, compiling a DEFMETHOD
will not add the method to that generic function.
The error-signalling behavior described in the specification of
DEFMETHOD in CLOS chapter 2 (if the function isn't a generic function
or if the lambda-list is not congruent) happens only at run time,
not at compile time.
DEFINE-METHOD-COMBINATION:
* The method combination can be used in a subsequent DEFGENERIC. If it
is referenced, the body of a long form of method combination must be
evaluable at compile-time.
Rationale:
The compile-time behavior of DEFCLASS is similar to DEFSTRUCT or
DEFTYPE.
DEFGENERIC and DEFMETHOD are similar to DEFUN, which doesn't add the
function definition to the compile-time environment. Since generic
functions may be freely redefined between compile and run time (just
like any other function), a method may end up "belonging" to a
different generic function at load time than at compile time. This
is why it is inappropriate to signal errors about congruency problems
(etc) until the method is actually added to the generic function at
run time.
Some implementations compose effective methods at compile time, which
requires evaluating the body of the DEFINE-METHOD-COMBINATION at
compile time.
Proposal CLOS-MACRO-COMPILATION:NOT-SO-MINIMAL:
This is the same as proposal MINIMAL, except under DEFCLASS add:
* The class may be instantiated at compile-time. Provided the
appropriate methods are also defined at compile-time, this implies:
- The class can be used as the :METACLASS option of a later DEFCLASS.
- It can be used as the :GENERIC-FUNCTION-CLASS or :METHOD-CLASS option
of a DEFGENERIC, GENERIC-FUNCTION, GENERIC-FLET, or GENERIC-LABELS.
Rationale:
Being able to instantiate a class at compile-time is somewhat more
convenient for users.
Current Practice:
The items listed under DEFCLASS in proposal MINIMAL are fairly standard
programming style.
Flavors does not support compile-time instantiation of classes. It
does not make method combinations available at compile-time either, but
Moon considers that to be a bad design choice.
Cost to implementors:
Unknown.
Cost to users:
Unknown, but probably fairly small.
Note that for proposal NOT-SO-MINIMAL, users still have to ensure that
any methods on the class which may be invoked at compile-time are
fully defined. This includes the INITIALIZE-INSTANCE and
SHARED-INITIALIZE methods that are invoked by MAKE-INSTANCE.
Wrapping an (EVAL-WHEN (EVAL COMPILE LOAD) ...) around the appropriate
definitions will make sure they are fully defined at compile-time.
Alternatively, the definitions could be placed in a separate file,
which is loaded before compiling the file that depends on those
definitions.
Benefits:
Programmers can rely on programs that use the CLOS defining macros
being able to compile correctly in all implementations, without having
to wrap explicit EVAL-WHENs around every macro call.
Discussion:
This writeup is based on discussions between Moon, Gray, and
Loosemore, who are mostly in agreement on the things presented in
proposal MINIMAL. We have purposely avoided saying anything about
whether meta-objects representing the classes, methods, etc. get
created at compile-time, or whether such meta-objects are fully or
partially defined. The basic questions addressed by this issue are
what kinds of things can be defined and then used during compilation
of the same file that defines them, and what restrictions might apply.
These proposals are not completely compatible with the meta-object
protocol document (89-003). Gregor Kiczales says:
No one believes that what is written in draft 10 of the MOP is valid.
Sandra Loosemore says:
Although I admit I don't understand all of the issues involved with
the meta-object protocol, I prefer proposal MINIMAL over
NOT-SO-MINIMAL. I don't think leaving the issue of whether or not
classes can be instantiated at compile-time unspecified places an
undue burden on users, and it does leave more freedom for the
meta-object protocol to decide what the right behavior really is.
Dick Gabriel notes:
The question I have about the process going on with respect to the
CLOS-MACRO-COMPILATION issue is whether the fine-grained behavior of
CLOS under various compilation/evaluation situations is being
over-specified.
At this stage of the game I worry that we might go a little too far in
one direction in specification when we are actually engaged in design
work. This isn't intended to be a criticism of any committees, but I
would feel a lot more comfortable with a conservative specification
that defined well-formed programs being loaded or compiled in fresh
Common Lisps with a pretty simple eval-when model that is easier to
specify and which makes it easy for all but the hairiest
compilation-environment-frobbing programs to be written.
-------
∂23-Mar-89 1504 X3J13-mailer Issue: PATHNAME-WILD (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89 12:11:23 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563820; Thu 23-Mar-89 15:11:10 EST
Date: Thu, 23 Mar 89 15:10 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-WILD (Version 2)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323151049.1.KMP@BOBOLINK.SCRC.Symbolics.COM>
>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<
Please just ponder it and bring your comments to the meeting.
My notes say that at the Fairfax meeting, we (the Cleanup committee)
thought this was ready for vote. This was held up in hopes of a unified
pathname proposal which did not materialize, and then got lost in the
shuffle.
-kmp
-----
Issue: PATHNAME-WILD
References: Pathnames (pp410-413)
Category: ADDITION
Edit history: 21-Jul-88, Version 1 by Pitman
06-Oct-88, Version 2 by Pitman
Status: For Internal Discussion
Problem Description:
Some file systems provide more complex conventions for wildcards than
simple component-wise wildcards. For example,
"F*O" might mean:
- a normal three character name
- a three-character name, with the middle char wild
- at least a two-character name, with the middle 0 or more chars wild
- a wild match spanning multiple directories
">foo>*>bar" might imply:
- the middle directory is named "*"
- the middle directory is :WILD
- there may be zero or more :WILD middle directories
- the middle directory name matches any one-letter name
">foo>**>bar" might mean
- the middle directory is named "**"
- the middle directory is :WILD
- there may be zero or more :WILD middle directories
- the middle directory name matches any two-letter name
The CL pathname model does not provide a way to represent such wildcards,
which means, for example, that (MAKE-PATHNAME :NAME "F*O") cannot be
recognized by portable code as containing a wildcard.
CL code needs to at least be able to detect and possibly to manipulate
such wildcard pathnames.
Proposal (PATHNAME-WILD:NEW-FUNCTION):
Introduce the following function:
WILD-PATHNAME-P pathname &optional field-key [Function]
Tests a pathname for the presence of wildcard components.
If the first argument is not a pathname an error is signalled.
If no field-key is provided, or the field-key is NIL, this function
returns true if the argument pathname has any wildcard components.
Otherwise, it returns false.
If a non-null field-key is provided, it must be one of :HOST, :DEVICE,
:DIRECTORY, :NAME, :TYPE, or :VERSION. In this case, it returns true
if the argument pathname is wild in the indicated component. Otherwise,
it returns false.
Test Case:
#1: (WILD-PATHNAME-P (MAKE-PATHNAME :NAME :WILD)) => T
#2: (WILD-PATHNAME-P (MAKE-PATHNAME :NAME :WILD) :NAME) => T
#3: (WILD-PATHNAME-P (MAKE-PATHNAME :NAME :WILD) :TYPE) => NIL
#4: (WILD-PATHNAME-P (PATHNAME "S:>foo>**>")) => T ;Lispm
#4: (WILD-PATHNAME-P (PATHNAME :NAME "F*O")) => T ;Most places
Rationale:
If the programmer can at least detect wild pathnames reliably,
he can know to do something useful (give up, merge out the bothersome
components, call DIRECTORY for a list of matching pathnames, etc.)
Current Practice:
Presumably no implemenation supports the proposal exactly as stated.
Symbolics Genera provides the ability to do
(SEND pathname :WILD-P)
which returns a value such as NIL, :NAME, :TYPE, etc. In the case
that more than one field is wild, however, some information is lost.
Cost to Implementors:
Many implementations probably have a substrate which is capable of this
or something similar already. In such cases, it's a relatively small
matter to add the proposed interface.
Even in cases where an implementation doesn't have ready code, it's clearly
better for the implementor to write that code once and for all than to ask
each user of wildcarded code to write it (often more heuristically).
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Wild pathnames would continue to be mistaken for ordinary pathnames in
situations which CL pathnames cannot represent.
Benefits:
Portable user interfaces that prompt users for pathnames could more
reliably detect wildcard pathnames and more easily guard against
embarrassing behavior in such situations.
Aesthetics:
This change would make some portable code less kludgey.
Discussion:
Pitman supports PATHNAME-WILD:NEW-FUNCTION.
It would have been possible for this function to have accepted
a string as an argument (coercing it to a pathnames), but that
would have entailed adding an optional host argument. We opted
not to do this.
There was some question about the name. The name PATHNAME-WILD-P
suggests a ``slot'' of a pathname (like PATHNAME-HOST),
while WILD-PATHNAME-P suggests a type (like INPUT-STREAM-P).
The committee was split on what to call it. Since it is more
like a type than a slot, the name WILD-PATHNAME-P was chosen.
∂23-Mar-89 1503 X3J13-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 11:40:15 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA10248; Thu, 23 Mar 89 12:40:04 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12657; Thu, 23 Mar 89 12:39:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903231939.AA12657@defun.utah.edu>
Date: Thu, 23 Mar 89 12:39:58 MST
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 5
To: x3j13@sail.stanford.edu
This version of the writeup has had a few changes made to the error
language in items 2 and 3.
Forum: Compiler
Issue: COMPILE-ENVIRONMENT-CONSISTENCY
References: CLtL p. 68-69, 143, 321
RAM's "Compiler Cleanup Proposal #3"
Category: CLARIFICATION
Edit History: V1, 2 Sep 1988, Sandra Loosemore (initial draft)
V2, 9 Sep 1988, Sandra Loosemore (incorporate suggestions)
V3, 26 Oct 1988, Sandra Loosemore (add suggestion from Benson)
V4, 08 Mar 1989, Sandra Loosemore (wording changes)
V5, 22 Mar 1989, Sandra Loosemore (fix error language)
Problem Description:
CLtL does not clearly specify what aspects of the compiletime
environment the compiler (or other preprocessor) may "wire in" to code
being compiled. At what time (compiletime or runtime) are certain
kinds of definitions "captured"? What happens if these definitions
are not consistent at both compile and run times?
Proposal COMPILE-ENVIRONMENT-CONSISTENCY:CLARIFY:
The process of compilation causes certain kinds of information present
in the compiletime environment to be captured and incorporated into
the resulting compiled code. Other kinds of information may not be
captured until the compiled code is actually run.
Specifically:
(1) The following information *must* be present in the compiletime
environment for the program to be compiled correctly. This
information need not also be present in the runtime environment.
(a) In conforming code, macros referenced in the code being compiled
must have been previously defined in the compiletime environment.
The compiler must treat any form that is a list beginning with
a symbol that does not name a macro or special form as a function
call. (This implies that SETF methods must also be available at
compiletime.)
(b) In conforming code, proclamations for SPECIAL variables must
be made in the compiletime environment before any bindings of
those variables are processed by the compiler. The compiler
must treat any binding of an undeclared variable as a lexical
binding.
(2) The compiler *may* incorporate the following kinds of information
into the code it produces, if the information is present in the
compiletime environment and is referenced within the code being
compiled. Except where some other behavior is explicitly stated, when
the compiletime and runtime definitions are different, it is
unspecified which will prevail within the compiled code. It is also
permissible for implementations to signal an error at runtime to
complain about the discrepancy. In all cases, the absence of the
information at compiletime is not an error, but its presence may
enable the compiler to generate more efficient code.
(a) The compiler may assume that functions that are defined and
declared INLINE in the compiletime environment will retain the
same definitions at runtime.
(b) The compiler may assume that, within a named function, a
recursive call to a function of the same name refers to the
same function, unless that function has been declared NOTINLINE.
(c) COMPILE-FILE may assume that, in the absence of NOTINLINE
declarations, a call within the file being compiled to a named
function which is defined in that file refers to that function.
(This permits "block compilation" of files.) The behavior of
the program is unspecified if functions are redefined individually
at runtime.
(d) The compiler may assume that the signature (or "contract") of
all built-in Common Lisp functions will not change. In addition,
the compiler may treat all built-in Common Lisp functions as if
they had been proclaimed INLINE.
(e) The compiler may assume that the signature (or "contract") of
functions with FTYPE information available will not change. (See
issue FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS.)
(f) The compiler may "wire in" the values of symbolic constants
that have been defined with DEFCONSTANT in the compiletime
environment.
(g) The compiler can assume that type definitions made with DEFTYPE
or DEFSTRUCT in the compiletime environment will retain the same
definition in the runtime environment. It may also assume that
a class defined by DEFCLASS in the compiletime environment will
be defined in the runtime environment in such a way as to have
the same superclasses and metaclass. This implies that
subtype/supertype relationships of type specifiers will not
change between compiletime and runtime. (Note that it is not
an error for an unknown type to appear in a declaration at
compiletime, although it is reasonable for the compiler to
emit a warning in such a case.)
(h) The compiler may assume that if type declarations are present
in the compiletime environment, the corresponding variables and
functions present in the runtime environment will actually be of
those types; otherwise, the runtime behavior of the program is
undefined.
(3) The compiler *must not* make any additional assumptions about
consistency between the compiletime and runtime environments. In
particular:
(a) The compiler may not assume that functions that are defined
in the compiletime environment will retain the either the
same definition or the same signature at runtime, except
in situations (2a) through (2e) above.
(b) The compiler may not signal an error if it sees a call to a
function that is not defined at compiletime, since that function
may be provided at runtime.
Rationale:
This proposal generally reflects current practice.
Current Practice:
There don't seem to be any compilers around that do not implement the
provisions of item (1).
For item (2), most compilers (including Lucid) optimize self-recursive
calls by default. Most compilers also opencode data structure
accessors (such as CAR) at some level of optimization, and some code
much more complicated built-in functions inline as well. VaxLisp, for
example, normally compiles MEMBER inline. The Lucid compiler makes
use of type declarations to perform generic-to-specific
transformations on many arithmetic and sequence functions, which is
also a form of inlining. KCL performs block compilation by default,
and Lucid does so under certain conditions.
Cost to implementors:
Unknown, but probably minor.
Cost to users:
Since most implementations appear to be largely in conformance with the
proposal, users should notice little difference.
Benefits:
The presence of a definite specification of what may happen when will
help users structure their programs so they will compile correctly in
all Common Lisp implementations.
Discussion:
Most of the discussion on this issue has been centered on the
terminology describing error situations for item (2). In most cases
where there is an inconsistency between compile-time and run-time, the
results will be unpredictable but harmless. The major exception is
violation of type declarations, which is a "crash-and-burn" error in
many implementations.
There has also been some concern raised that item (3) would prohibit
such things as a cross-compiler that produces standalone programs in
an environment that disallows redefinition of functions. The intent
of this proposal is not to prohibit a compiler from having a magic
switch that imposes additional restrictions on the programs it
compiles, but such a compiler would not be a compiler for Common Lisp.
Several people have expressed reservations about items 2b and 2c, saying
that self-tail-recursion optimization and block compilation should not
be the default behavior of the compiler. Gail Zacharias responds:
This item [2c] has nothing to do with whether anybody does it by
default. The question is whether an end user can take a Common Lisp
program whose internals he's not familiar with, block-compile it, and
be guaranteed that it will continue to function correctly. This item
says that yes, a correct CL program must explicitly indicate what
functions in the source it will redefine at runtime. I don't think
this places such a great burden on the programmer. Without this
provision, only somebody intimately familiar with a program could know
whether it can be safely block-compiled, making block-compilation
useless in the context of portable CL programs.
This thing about "block compilation shouldn't be the default" seems to
come up every time this item is discussed. That's an environment
question and is not addressed by the proposal. The proposal simply
says that block compilation should be legal.
-------
∂23-Mar-89 1503 X3J13-mailer Issue: REMF-DESTRUCTION-UNSPECIFIED, v.6
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 23 Mar 89 12:25:28 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 23 MAR 89 12:07:04 PST
Date: 23 Mar 89 12:06 PST
From: masinter.pa@Xerox.COM
to: x3J13@sail.stanford.edu
Subject: Issue: REMF-DESTRUCTION-UNSPECIFIED, v.6
Message-ID: <890323-120704-5187@Xerox>
This issue was tabled from the Jan. 89 meeting, and amended
by Barry Margolin as discussed there.
!
Issue: REMF-DESTRUCTION-UNSPECIFIED
References: (SETF (GET ...) ...), REMPROP, (SETF (GETF ...) ...),
REMF (pp165-167); NREVERSE (p248); DELETE, DELETE-IF,
DELETE-DUPLICATES, NSUBSTITUTE, NSUBSTITUTE-IF (pp254-256);
NCONC, NRECONC (p269); NUNION, NINTERSECTION,
NSET-EXCLUSIVE-OR (pp276-279).
Category: CLARIFICATION/CHANGE
Edit history: 11-Feb-87, Version 1 by Dave Andre (DLA@Symbolics.COM)
29-Oct-87, Version 2 by Pitman (flesh out proposals)
28-Nov-88, Version 3 by Pitman (revised presentation)
29-Nov-88, Version 4 by Pitman (slight editing per DLA)
15-Mar-89, Version 5 by Margolin (amendments discussed in
Hawaii, removed -NOT functions)
17-Mar-89, Version 6 by Margolin (make NSUBSTITUTE* less vague)
Problem Description:
Currently, the exact nature of the side-effect performed by list
modification routines is not specified.
Either the specific modifications allowed should be specified so that
programmers can rely on them and implementors can avoid accidentally
causing problems by introducing well-meaning optimizations, or else
the documentation should explicitly state that the effects are
unspecified so that programmers will not depend on them and
implementors will feel comfortable about doing interesting optimizations.
Proposal (REMF-DESTRUCTION-UNSPECIFIED:EXPLICITLY-VAGUE-EXCEPT-NCONC-AND-NSUBSTITUTE):
[This proposal name is getting way out of hand!]
Clarify that the way in which the destructive behavior of the
operators below is achieved is explicitly vague in a number of ways,
in order to provide individual implementations the necessary
flexibility to do useful optimizations.
(SETF (GETF place indicator) value)
is permitted to either SETF place or to SETF any part, CAR or
CDR, of the top-level list structure held by that place.
(REMF place indicator)
is permitted to either SETF place or to SETF any part, CAR or
CDR, of the top-level list structure held by that place.
(SETF (GET symbol indicator) value)
is constrained to behave exactly the same as
(SETF (GETF (SYMBOL-PLIST symbol) indicator) value).
(REMPROP symbol indicator)
is constrained to behave exactly the same as
(REMF (SYMBOL-PLIST symbol) indicator).
(NREVERSE sequence)
when sequence is a list, is permitted to SETF any part, CAR or
CDR, of the top-level list structure in that sequence.
when sequence is an array is permitted to re-order the elements
of the given sequence in order to produce the resulting array.
(DELETE object sequence ...)
when sequence is a list, is permitted to SETF any part, CAR or
CDR, of the top-level list structure held in that sequence.
when sequence is an array is permitted to change the dimensions
of the array and to slide its elements into new positions without
permuting them to produce the resulting array.
(DELETE-IF test sequence ...)
is constrained to behave exactly like
(DELETE NIL sequence
:TEST #'(LAMBDA (IGNORE ITEM) (FUNCALL test ITEM))
...).
(DELETE-DUPLICATES sequence ...)
when sequence is a list, is permitted to SETF any part, CAR or
CDR, of the top-level list structure held in that sequence.
when sequence is an array is permitted to change the dimensions
of the array and to slide its elements into new positions without
permuting them to produce the resulting array.
(NRECONC list tail)
is constrained to have side-effect behavior equivalent to:
(NCONC (NREVERSE list) tail).
(NUNION list1 list2 ...)
(NINTERSECTION list1 list2 ...)
(NSET-EXCLUSIVE-OR list1 list2 ...)
is permitted to SETF any part, CAR or CDR, of the top-level of
any of the given lists.
Note, however, that since this side-effect is not required,
these functions should still not be used in for-effect-only
positions in portable code.
(NCONC . lists)
is defined using the following recursive relationship:
(NCONC) => NIL
(NCONC NIL . args) == (NCONC . args)
(NCONC arg) => arg
(NCONC arg1 arg2) has the side effect of (RPLACD (LAST arg1) arg2),
and returns arg1
(NCONC arg1 arg2 . args) == (NCONC (NCONC arg1 arg2) . args)
[If a previous cleanup issue prohibited NIL as a non-last argument
then ignore the (NCONC NIL . args) case.]
(NSUBSTITUTE new-object old-object sequence ...)
(NSUBSTITUTE-IF new-object test sequence ...)
is required to SETF any CAR (if SEQUENCE is a list) or VREF (if it's
a vector) of SEQUENCE which is required to be replaced with
NEW-OBJECT. If SEQUENCE is a list, it none of the CDRs of the
top-level list may be modified. These functions, therefore, may be
used in for-effect-only positions in code (some may find this
stylistically distasteful, though).
Note: The above clarifications are not intended as complete functional
descriptions. They are intended to augment (rather than to replace)
other descriptions already in effect.
Test Cases:
For GETF...
(SETQ FOO (LIST 'A 'B 'C 'D 'E 'F)) ==> (A B C D E F)
(SETQ BAR (CDDR FOO)) ==> (C D E F)
(REMF FOO 'C)
BAR ==> ??
In Symbolics Common Lisp, BAR holds (C D E F).
CLtL allows other interpretations. eg, BAR might hold
(C), (NIL), (C NIL) or (C D).
Under this proposal, any of these interpretations (and others as well)
would still be valid
For DELETE...
(SETQ FOO (LIST 'A 'B 'C)) ==> (A B C)
(SETQ BAR (CDR FOO)) ==> (B C)
(SETQ FOO (DELETE 'B FOO)) ==> (A C)
BAR ==> ??
(EQ (CDR FOO) (CAR BAR)) ==> ??
In Symbolics Common Lisp, these last two expressions return ((C)) and T.
Under this proposal, either of these interpretations (and others
as well) would be valid.
For NCONC...
(SETQ FOO (LIST 'A 'B 'C 'D 'E)
BAR (LIST 'F 'G 'H 'I 'J)
BAZ (LIST 'K 'L 'M)) => (K L M)
(SETQ FOO (NCONC FOO BAR BAZ)) => (A B C D E F G H I J K L M)
FOO => (A B C D E F G H I J K L M)
BAR => (F G H I J K L M)
BAZ => (K L M)
(SETQ FOO (LIST 'A 'B 'C 'D 'E)
BAR (LIST 'F 'G 'H 'I 'J)
BAZ (LIST 'K 'L 'M)) => (K L M)
(SETQ FOO (NCONC NIL FOO BAR NIL BAZ)) => (A B C D E F G H I J K L M)
FOO => (A B C D E F G H I J K L M)
BAR => (F G H I J K L M)
BAZ => (K L M)
Rationale:
Implementations already vary widely on their implementation techniques
for these functions. This effectively clarifies the status quo, making
it more clear to programmers what they may rely upon in portable code.
In the case of NCONC, however, the precise definition is useful because
it is what users expect, it is how NCONC has been defined for many
years, and it is how current implementations generally work. It may
not always be the most efficient way (e.g. it may result in invisible
pointers in CDR-coded implementations), but callers of NCONC probably
use it specifically for its precise side effects.
In the case of NSUBSTITUTE, this seems like the only reasonable
implementation mechanism, and there doesn't seem to be a reason not to
guarantee it.
Current Practice:
All valid implementations are believed to comply with the vague
definitions. Symbolics Genera 7.2 and Sun Common Lisp 2.1.3 appear to
conform to the NCONC spec.
Cost to Implementors:
None. This is probably the status quo for most implementors. If there
are any implementations that don't implement NCONC and NSUBSTITUTE as
above (which I doubt) they will have to be changed.
Cost to Users:
This change would not affect programs coded with "good programming
practice". That is, only programs which rely on currently undocumented
features would be in any danger of breaking. In fact, those programs
are already in such danger, and this change to the documentation would
just publicize it. The clarification would -encourage- good programming
practice by warning people to only obey the published contract of the
above-mentioned functions.
There is, however, no automatic technique for making this check for
programs already in error. Bugs due to unexpected side-effects are in
general among the hardest to reckon with.
Cost of Non-Adoption:
Programmers may naively believe there is only one possible or reasonable
implementation of these functions. Some implementors may shy away from
reasonable optimizations out of a paranoid belief that deviating from
some vague, unspoken rules will lead to programmer unrest. Making these
things explicitly vague clarifies the implementor's rights in a way that
permits numerous useful optimizations.
Benefits:
Users would be discouraged from taking advantage of subtle details
of these destructive operations because such details would be explicitly
not guaranteed to be portable.
Implementations can improve performance of many of the above-mentioned
functions when they are not under the constraint to implement them
in a highly constrained fashion. For example, in Symbolics systems,
DELETE of a cdr-coded list could use the implementation primitive
%CHANGE-LIST-TO-CONS rather than RPLACD to avoid creating forwarding
pointers.
Garbage collection effectiveness can also be improved. For example,
all of the destructive operations which remove objects (eg, REMF)
could remove CAR pointers to removed objects which are more volatile
than the list itself, assisting the garbage collector and thereby
improving memory usage and paging performance.
Tightening the definition of NCONC and NSUBSTITUTE permits users to
predict their programs' behavior more precisely.
Non-Benefits:
Users who inadvertently depend on side-effect behavior may be rudely
surprised when moving between implementations.
Compatibility with older Lisp dialects is diminished.
Implementors have less flexibility in implementing NCONC efficiently.
This is true of NSUBSTITUTE, but this is less likely to cause problems.
Performance Impact:
Metering in Symbolics test systems have shown that there are substantial
performance gains to be had by allowing implementations flexibility in
these areas.
In the case of NCONC, this implementation flexibility, and hence
potential performance improvements, is sacrificed.
If anyone ever invents CAR-coding, the required implementation of
NSUBSTITUTE could be a performance hindrance.
Aesthetics:
Most of these functions implement abstract operations. For example,
REMPROP implements an abstract operation on a "property list".
Proper language design should not encourage people to delve below the
level of abstraction into the nitty gritty.
NCONC is a "less abstract" function than the rest of the functions
described above. It is usually used precisely because of the way it
interacts with list implementation. Similarly for NSUBSTITUTE.
Discussion:
Andre's original version of this proposal pushed for explicitly vague
descriptions of these functions' side-effect behavior. He believes
that if users want more predictability from these functions, they
should write private variants that implement whatever predictability
they require.
Pitman originally opposed this position because he weighed portability
a higher concern. Since the original discussion, however, his views on
how to resolve this priority have been refined, and he now believes
that leaving things vague is appropriate. As such, he now supports what
is effectively Andre's original proposal.
Pitman and Andre supported version 4. [I don't know how they feel
about v6 -- Barmar].
Moon supports version 6.
∂23-Mar-89 1504 X3J13-mailer issue COMPILER-DIAGNOSTICS, version 10
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 12:13:08 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA11279; Thu, 23 Mar 89 13:13:03 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12687; Thu, 23 Mar 89 13:13:00 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232013.AA12687@defun.utah.edu>
Date: Thu, 23 Mar 89 13:12:58 MST
Subject: issue COMPILER-DIAGNOSTICS, version 10
To: x3j13@sail.stanford.edu
This writeup has also had some minor changes to error terminology
made, under the section on warnings (2b). I've also added a couple of
notes to the discussion section on issues that have come up but that
have not yet been resolved.
Forum: Compiler
Issue: COMPILER-DIAGNOSTICS
References: CLtL p. 438-439, 62, 69, 160, 161
Condition System, Revision #18
S:>KMP>cl-conditions.text.34
Issue GC-MESSAGES
Issue RETURN-VALUES-UNSPECIFIED
Issue COMPILER-VERBOSITY
Issue CONDITION-RESTARTS
Category: CLARIFICATION, ENHANCEMENT
Edit History: V1, 15 Oct 1988, Sandra Loosemore
V2, 19 Oct 1988, Sandra Loosemore (minor fixes)
V3, 25 Oct 1988, Sandra Loosemore (input from Pitman & Gray)
V4, 01 Nov 1988, Sandra Loosemore (fix typos)
V5, 15 Dec 1988, Dan L. Pierson (new condition types)
V6, 15 Dec 1988, Sandra Loosemore (additions, fix wording)
V7, 16 Dec 1988, Dan L. Pierson (minor cleanup)
V8, 07 Jan 1989, Sandra Loosemore (expand discussion)
V9, 26 Jan 1989, Sandra Loosemore (simplify)
V10, 22 Mar 1989, Sandra Loosemore (error terminology)
Status: Ready for release
Problem Description:
It is unclear whether various diagnostics issued by the compiler are
supposed to be true errors and warnings, or merely messages.
In some implementations, COMPILE-FILE handles even serious error
situations (such as syntax errors) by printing a message and then
trying to recover and continue compiling the rest of the file, rather
than by signalling an error. While this user interface style is just
as acceptable as invoking the debugger, it means that a normal return
from COMPILE-FILE does not necessarily imply that the file was
successfully compiled.
Many compilers issue warnings about programming style issues (such as
binding a variable that is never used but not declared IGNORE).
Sometimes these messages obscure warnings about more serious problems,
and there should be some way to differentiate between the two. For
example, it should be possible to suppress the style warnings.
Also, neither CLtL nor issue RETURN-VALUES-UNSPECIFIED states what the
return value from COMPILE-FILE should be.
Proposal COMPILER-DIAGNOSTICS:USE-HANDLER:
(1) Introduce a new condition type, STYLE-WARNING, which is a subtype
of WARNING.
(2) Clarify that ERROR and WARNING conditions may be signalled within
COMPILE or COMPILE-FILE, including arbitrary errors which may
occur due to compile-time processing of (EVAL-WHEN (COMPILE) ...)
forms or macro expansion.
Considering only those conditions signalled -by- the compiler (as
opposed to -within- the compiler),
(a) Conditions of type ERROR may be signalled by the compiler in
situations where the compilation cannot proceed without
intervention.
Examples:
file open errors
syntax errors
(b) Conditions of type WARNING may be signalled by the compiler in
situations where the standard explicitly states that a warning must,
should, or may be signalled; and where the compiler can determine
that a situation with undefined consequences or that would cause
an error to be signalled would result at runtime.
Examples:
violation of type declarations
SETQ'ing or rebinding a constant defined with DEFCONSTANT
calls to built-in Lisp functions with wrong number of arguments
or malformed keyword argument lists
referencing a variable declared IGNORE
unrecognized declaration specifiers
(c) The compiler is permitted to signal diagnostics about matters of
programming style as conditions of type STYLE-WARNING. Although
STYLE-WARNINGs -may- be signalled in these situations, no
implementation is -required- to do so. However, if an
implementation does choose to signal a condition, that condition
will be of type STYLE-WARNING and will be signalled by a call to
the function WARN.
Examples:
redefinition of function with different argument list
calls to function with wrong number of arguments
unreferenced local variables not declared IGNORE
declaration specifiers described in CLtL but ignored by
the compiler
(3) Require COMPILE and COMPILE-FILE to handle the ABORT restart by
aborting the smallest feasible part of the compilation. State that
both COMPILE and COMPILE-FILE are allowed to establish a default
condition handler. If such a condition handler is established,
however, it must first resignal the condition to give any
user-established handlers a chance to handle it. If all user error
handlers decline, the default handler may handle the condition in an
implementation-specific way; for example, it might turn errors into
warnings.
(4) Specify that COMPILE-FILE returns two values. The first value
is the truename of the output file, or NIL if the file could not be
created. The second value is T if the file was compiled without
errors, or NIL if errors were signalled during compilation.
Rationale:
Introducing the STYLE-WARNING condition allows handlers to distinguish
between potentially serious problems and mere kibitzing on the part of
the compiler.
Requiring any condition handlers established by the compiler to resignal
the condition before proceeding with any implementation-specific action
gives user error handlers a chance to override the compiler's default
behavior. For example, the user error handler could invoke a restart
such as ABORT or MUFFLE-WARNING.
Requiring the compiler to handle the ABORT restart reflects what
several implementations already do (although probably not using this
mechanism). The intent of the wording is to allow an implementation
to abort the entire compilation if it is not feasible to abort a
smaller part.
Requiring a second success-p value to be returned from COMPILE-FILE
gives the user some indication of whether there were serious problems
encountered in compiling the file.
Test Case/Example:
Here is an example of how COMPILE-FILE might set up its condition
handlers. It establishes an ABORT restart to abort the compilation
and a handler to take implementation-specific action on ERROR
conditions. Note that INTERNAL-COMPILE-FILE may set up additional
ABORT restarts.
(defvar *output-file-truename* nil)
(defun compile-file (input-file &key output-file)
(let ((*output-file-truename* nil)
(errors-detected nil))
(with-simple-restart (abort "Abort compilation.")
(handler-bind ((error #'(lambda (condition)
(setq errors-detected t)
(signal condition)
...)))
(internal-compile-file input-file output-file)))
(values *output-file-truename*
errors-detected)))
Current Practice:
No implementation behaves exactly as specified in this proposal.
In VaxLisp, COMPILE-FILE handles most compile-time errors without
invoking the debugger. (It gives up on that top-level form and moves on
to the next one.) Instead of signalling errors or warnings, it simply
prints them out as messages.
In Lucid Common Lisp, COMPILE-FILE invokes the debugger when it encounters
serious problems. COMPILE-FILE returns the pathname for the output file.
Symbolics Genera usually tries to keep compiling when it encounters errors;
so does Symbolics Cloe.
On the TI Explorer, the compiler tries to catch most errors and turn
them into warnings (except for errors on opening a file), but the user
can change special variable COMPILER:WARN-ON-ERRORS to NIL if he wants
to enter the debugger on an error signalled during reading, macro
expansion, or compile-time evaluation. The true name of the output
file is returned as the first value. A second value indicates whether
any errors or warnings were reported.
IIM Common Lisp's compiler handles errors using a resignalling mechanism
similar to what is described here.
Cost to implementors:
The cost to implementors is not trivial but not particularly high. This
proposal tries to allow implementations considerable freedom in what
kinds of conditions the compiler must detect and how they are handled,
while still allowing users some reasonably portable ways to deal with
compile-time errors.
Cost to users:
This is a compatible extension. This proposal may cause users to see
some small differences in the user interface to the compiler, but
implementations already vary quite widely in their approaches. Some
users will probably have to make some minor changes to their code.
Adding the STYLE-WARNING type may cause conflicts with programs
already using that name.
Benefits:
Users are given a way to detect and handle compilation errors, which
would simplify the implementation of portable code-maintenance
utilities. The behavior of the compiler in error situations is made
more uniform across implementations.
Discussion:
The issue of whether the compiler may print normal progress messages
is discussed in detail in a separate issue, COMPILER-VERBOSITY.
Explicit calls to ERROR don't really justify warnings to be signalled
at compile-time, but we assume implementors have some common sense
about when it's appropriate to do so.
Proposal CONDITION-RESTARTS:PERMIT-ASSOCIATION would make it illegal
for conditions to be resignalled. If that proposal is accepted, the
wording here would have to be changed to indicated that the compiler's
condition handler makes a copy of the condition and signals that.
Moon says:
I think [requiring the ABORT restart to be handled] is wrong. The only
documentation of the ABORT restart that I could find says
The purpose of the ABORT restart is generally to allow return to the
innermost ``command level.''
I agree with this, and I believe it means that it is wrong for any
function other than one that establishes a read-eval-print loop or
a command-level to establish an ABORT restart. It would be useful
to have some restart that aborts a portion of the compilation, but
it should be given some other name.
-------
∂23-Mar-89 1503 X3J13-mailer issue COMPILED-FUNCTION-REQUIREMENTS, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 11:56:51 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA10754; Thu, 23 Mar 89 12:56:42 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12677; Thu, 23 Mar 89 12:56:39 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903231956.AA12677@defun.utah.edu>
Date: Thu, 23 Mar 89 12:56:37 MST
Subject: issue COMPILED-FUNCTION-REQUIREMENTS, version 5
To: x3j13@sail.stanford.edu
Some people have spoken up in favor of restoring the proposal FLUSH
that was present in an earlier version of this proposal, so here it is
(combined with a further change to COMPILE that some people have
requested). It's my impression that proposal FLUSH has more support
now than it used to.
Forum: Compiler
Issue: COMPILED-FUNCTION-REQUIREMENTS
References: CLtL p. 32, 76, 112, 143, 438-439
Issue FUNCTION-TYPE (passed)
Issue COMPILER-LET-CONFUSION
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue LOAD-TIME-EVAL (passed)
Issue COMPILE-ENVIRONMENT-CONSISTENCY
Issue COMPILE-ARGUMENT-PROBLEMS
Category: CLARIFICATION
Edit History: V1, 3 Jan 1989 Sandra Loosemore
V2, 10 Jan 1989, Sandra Loosemore (additional proposal)
V3, 10 Feb 1989, Sandra Loosemore (new proposal)
V4, 11 Mar 1989, Sandra Loosemore (fix wording to agree
with other pending proposals)
V5, 23 Mar 1989, Sandra Loosemore (restore proposal FLUSH)
Status: Ready for release
Problem Description:
There is confusion about what functions might be or must be of type
COMPILED-FUNCTION, and what attributes must be true of
COMPILED-FUNCTIONs. Is the distinction between COMPILED-FUNCTIONs and
other functions only one of representation, or can user programs infer
anything about COMPILED-FUNCTIONs? Are implementations required to
distinguish between compiled and non-compiled functions?
CLtL defines a COMPILED-FUNCTION as "a compiled code object". (Issue
FUNCTION-TYPE says only that COMPILED-FUNCTION must be a subtype of
FUNCTION.) Although it is not explicitly stated, CLtL implies that
compiled code must conform to certain rules; in particular, it states
that all macros are expanded at compile time, and specifies different
behavior for the COMPILER-LET and the EVAL-WHEN special forms
depending on whether they are interpreted or compiled.
The description of COMPILE in CLtL says that "a compiled-function object
[is] produced". It is not clear to everyone whether this implies that
COMPILED-FUNCTION-P must be true of such functions. CLtL says nothing
about whether functions defined in files compiled with COMPILE-FILE and
subsequently loaded must be of type COMPILED-FUNCTION.
The proposals presented below present a simple model of the
compilation process. A minimal compiler could be implemented to
perform a code walk to apply the indicated transformations to the
function source code. Of course, most compilers will perform other
transformations as well, such as translating the Lisp source code into
a representation that is more compact or which can be executed more
efficiently.
Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN:
(1) Clarify that if a function is of type COMPILED-FUNCTION, the
following are guaranteed about the function:
- All macro calls appearing lexically within the function have
already been expanded and will not be expanded again when the
function is called. (See CLtL p. 143.) The process of
compilation effectively turns MACROLET and SYMBOL-MACROLET
constructs into PROGNs with all instances of the local macros
in the body fully expanded.
- The compiler must capture declarations to determine whether
variable bindings and references appearing lexically within
the function are to be treated as lexical or special.
- COMPILER-LETs nested lexically within the function will not bind
any variables when the function is called (CLtL p. 112). Again,
the process of compilation effectively turns COMPILER-LET
constructs into PROGNs with all macros in the body fully expanded.
- Lexically nested EVAL-WHENs have been processed as stated in
proposal EVAL-WHEN-NON-TOP-LEVEL; either the body is treated as
an implicit PROGN or as the constant NIL.
- If the function contains lexically nested LOAD-TIME-VALUE forms,
these have already been pre-evaluated and will not be evaluated
again when the function is called.
(2) Implementations are free to classify all functions as
COMPILED-FUNCTIONs, provided that all functions satisfy the criteria
listed in item (1). It is also permissible for functions that are
not COMPILED-FUNCTIONs to satisfy the above criteria.
(3) Clarify that COMPILE always produces an object of type
COMPILED-FUNCTION. Clarify when functions are defined in a
file which is compiled with COMPILE-FILE, and the compiled file is
subsequently LOADed, objects of type COMPILED-FUNCTION result.
Rationale:
This proposal allows users to count on COMPILE and COMPILE-FILE always
producing objects that are COMPILED-FUNCTION-P.
It assigns some specific properties to compiled functions. Users would
be able to rely on any function which is of type COMPILED-FUNCTION having
really been (at least partially) compiled.
It also states what many people believe to be the minimum functionality
required of a compiler.
Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN-COMPILE:
(1) Clarify that functions produced by COMPILE, or defined in a file
produced by COMPILE-FILE which has been subsequently LOADed, must
satisfy the same requirements listed in section (1) of proposal
TIGHTEN.
(2) Clarify that COMPILE always produces an object of type
COMPILED-FUNCTION. Clarify when functions are defined in a
file which is compiled with COMPILE-FILE, and the compiled file is
subsequently LOADed, objects of type COMPILED-FUNCTION result.
Rationale:
This proposal allows users to count on COMPILE and COMPILE-FILE always
producing objects that are COMPILED-FUNCTION-P.
It also states what many people believe to be the minimum functionality
required of a compiler.
However, it allows functions that have not been compiled also to be of
type COMPILED-FUNCTION. For implementations that do not use different
representations for interpreted and compiled functions, it would still
allow COMPILED-FUNCTION and FUNCTION to be synonymous, even if
interpreted functions do not satisfy the requirements for compilation.
Proposal COMPILED-FUNCTION-REQUIREMENTS:FLUSH:
(1) Remove the type specifier COMPILED-FUNCTION and the predicate
COMPILED-FUNCTION-P from the language.
(2) Clarify that functions defined in a file produced by COMPILE-FILE
which has been subsequently LOADed, must satisfy the same
requirements listed in section (1) of proposal TIGHTEN.
(3) Remove the language from proposal COMPILE-ARGUMENT-PROBLEMS:CLARIFY
that says "it is an error" to try to COMPILE a function that was
defined interpretively in a non-null lexical environment.
Instead, state that if COMPILE cannot compile the function, it
should simply behave as an identity operation.
Rationale:
Distinguishing between compiled and non-compiled functions is of
little use to portable programs.
Some people believe that it should be valid to call COMPILE on any
function, and that it should be legitimate for COMPILE to do nothing.
Current Practice:
It appears that most implementations currently distinguish compiled
versus non-compiled functions on the basis of representation. It seems
unlikely that any implementation would have problems satisfying the
stated minimum requirements for compilation.
Lucid uses the same representation for both compiled and non-compiled
functions, except there is a bit in the header used to distinguish them.
A-Lisp uses the same representation for both compiled and interpreted
functions and currently labels them both as COMPILED-FUNCTION, but the
implementation of COMPILED-FUNCTION-P could be easily fixed to
distinguish "real" compiled functions.
On the TI Explorer, the COMPILE function can return an object of
either type COMPILED-FUNCTION or LEXICAL-CLOSURE, where the latter
consists of two components -- an environment and a COMPILED-FUNCTION.
There is confusion about whether microcoded functions should be
considered compiled or not.
Cost to implementors:
Unknown, but probably small for either proposal. Proposal
TIGHTEN-COMPILE is probably most consistent with current practice.
Cost to users:
Probably minimal. Since the COMPILED-FUNCTION type specifier is
currently ill-defined, it is hard to imagine that existing programs
can portably rely on any interpretation of what it means that is
inconsistent with what is presented here.
Benefits:
The specification of what the compiler must do is made more explicit.
Discussion:
The FIXNUM and BIGNUM types were also defined in CLtL solely on the
basis of distinguished representations, and that this definition has
proved inadequate for just about all portable usages of these type
specifiers. Defining COMPILED-FUNCTION solely on the basis of
distinguished representation seems like a bad idea.
David Gray notes:
We make good use of the type COMPILED-FUNCTION in our implementation,
but all of the accessor functions for objects of that type are
non-standard, which makes me wonder if it might be best to just remove
this type from the standard along with BIGNUM.
One use of the COMPILED-FUNCTION type is in declarations. A-Lisp and
Lucid, for example, can compile FUNCALL more efficiently if it can be
determined that the function is of type COMPILED-FUNCTION. However,
in order for such declarations to be really useful, there should be a
way to construct an object which is guaranteed to be of type
COMPILED-FUNCTION. Both of the proposals presented require COMPILE
and COMPILE-FILE to construct compiled functions.
Moon says:
I much prefer the option FLUSH...
This type has no portable meaning and never should have existed.
Pierson says:
What I (and believe Kent) want is a guarantee that [COMPILE] won't
signal an error; if nothing else works COMPILE will simply apply
#'IDENTITY to the symbol's function. Specifically, it should be
legal and safe to attempt to speed up my current program(s) by
doing:
(DO-SYMBOLS (SYM <my-package>)
(WHEN (FBOUNDP SYM) (COMPILE SYM)))
-------
∂23-Mar-89 1512 X3J13-mailer issue COMPILER-LET-CONFUSION, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:07:47 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA17346; Thu, 23 Mar 89 16:07:29 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12792; Thu, 23 Mar 89 16:07:25 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232307.AA12792@defun.utah.edu>
Date: Thu, 23 Mar 89 16:07:23 MST
Subject: issue COMPILER-LET-CONFUSION, version 8
To: x3j13@sail.stanford.edu
This version fixes the bug in the example code that was pointed out
earlier, and clarifies the relation between COMPILER-LET and
DEFINE-OPTIMIZER.
There has been some discussion that COMPILER-LET might be implemented
by storing its variable bindings in the lexical environment. Some of
us think that this would result in a significant change to the
semantics of COMPILER-LET that would be inappropriate to pursue at
this time, and in any case there hasn't been a proposal submitted yet
that addresses all of the issues involved.
Issue: COMPILER-LET-CONFUSION
Forum: Compiler
References: CLtL p. 112
Issue DEFINE-OPTIMIZER
Category: CHANGE
Edit History: V1, 27 Sep 1988, Sandra Loosemore (initial version)
V2, 04 Oct 1988, Sandra Loosemore (add another example)
V3, 31 Oct 1988, Sandra Loosemore (only proposal ELIMINATE)
V4, 08 Jan 1989, Kent M. Pitman (new alternative)
V5, 09 Jan 1989, Sandra Loosemore (discussion)
V6, 08 Mar 1989, Sandra Loosemore (general updating)
V7, 13 Mar 1989, Sandra Loosemore (fix bug from V6)
V8, 23 Mar 1989, Sandra Loosemore (fix another bug, add
to discussion)
Problem Description:
The description of the COMPILER-LET special form in CLtL is confusing
to many people. There are no examples provided to make it clear how it
is supposed to be used. The only description which is offered is overly
concrete, which has led to confusion about the intent of COMPILER-LET,
and about its implementability.
The intent of COMPILER-LET was to permit information to be communicated
between macros by use of dynamic variables at macroexpansion time.
It was not necessary to the intended uses of COMPILER-LET that such
variables ever be bound at execution time.
Unfortunately, probably because some implementations did not primitively
support COMPILER-LET at the time CLtL was written, an exception was
permitted to make COMPILER-LET `more or less work' in interpreters:
the COMPILER-LET variables were permitted to be bound at execution time.
The problem was further compounded by the fact that CLtL presented this
exception as part of COMPILER-LET's contract rather than as an
implementation note, and by the fact that no examples of actually using
COMPILER-LET correctly are provided.
One particular case where problems have resulted is a situation like
(compiler-let ((*v* 1))
#'(lambda () (m)))
where M is a macro that refers to *V*. In some implementations, M is
not macroexpanded until the dynamic extent of the *V* binding has
ended.
Subtle bugs can be introduced because of the different handling of the
variable bindings in the interpreter and the compiler. In compiled
code, the bindings are only lexically visible during the expansion of
macros at compile time, while in interpreted code the bindings have
dynamic scope and may also be seen during ordinary evaluation if
evaluation and macroexpansion happen "in parallel".
Further compatibility problems can result from the value forms being
evaluated in a null lexical environment in the compiler and the ordinary
lexical environment in the interpreter.
Background and Analysis:
It should be clear up front that COMPILER-LET is not computationally
essential. Most (if not all) uses of it can be rewritten using MACROLET
or SYMBOL-MACROLET.
A typical use of COMPILER-LET might be:
(defvar *local-type-declarations* '())
(defmacro local-type-declare (declarations &body forms)
`(compiler-let ((*local-type-declarations*
(append ',declarations *local-type-declarations*)))
,@forms))
(defmacro typed-var (var)
(let ((type (assoc var *local-type-declarations*)))
(if type `(the ,(cadr type) ,var) var)))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
The same thing could be accomplished using MACROLET:
(defmacro local-type-declare (declarations &body forms)
(local-type-declare-aux declarations forms))
(defmacro typed-var (var) var)
(eval-when (eval compile load)
(defun local-type-declare-aux (declarations forms)
`(macrolet ((typed-var (var)
(let ((type (assoc var ',declarations)))
(if type `(the ,(cadr type) ,var) var)))
(local-type-declare (new-declarations &body new-forms)
(local-type-declare-aux
(append new-declarations ',declarations)
new-forms)))
,@forms)))
A further alternative would be to use SYMBOL-MACROLET (this particular
implementation assumes that issue DEFINING-MACROS-NON-TOP-LEVEL passes):
(let ((temp (gensym)))
(defmacro local-type-declare (declarations &body forms &environment env)
`(symbol-macrolet ((,temp ',(append declarations
(symbol-macro-value temp env))))
,@forms))
(defmacro typed-var (var &environment env)
(let ((type (assoc var (symbol-macro-value temp env))))
(if type `(the ,(cadr type) ,var) var)))
)
(defun symbol-macro-value (symbol env &optional default)
(multiple-value-bind (expansion macro-p) (macroexpand symbol env)
(if macro-p (eval expansion) default)))
Opinion is divided as to which is more understandable. Some
people find the COMPILER-LET idiom more understandable (assuming that
it can be made to work consistently in compiled and interpreted
code), while others find it just as natural to use MACROLET or
SYMBOL-MACROLET.
The issues are these:
- Is it possible to implement COMPILER-LET in a usefully consistent
way in all implementations?
- Are the benefits of providing a useful and compatible implementation
of COMPILER-LET worth any associated cost?
Two proposals are presented below:
- Option REPAIR argues that COMPILER-LET provides interesting
functionality that can be implemented in a manner that is usefully
consistent across implementations, and that the associated cost
is low enough for it to be worthwhile to do so.
- Option ELIMINATE argues that COMPILER-LET complicates the language
and that providing this construct is not worth the associated
implementation cost.
Proposal (COMPILER-LET-CONFUSION:REPAIR):
Strike the existing definition of COMPILER-LET. Redefine it as follows:
COMPILER-LET [Special form]
COMPILER-LET is similar to LET, but it always makes special
bindings and makes those bindings visible only during
macroexpansion of forms in the body, not during the runtime
execution of those forms.
If proposal DEFINE-OPTIMIZER:NEW-FACILITY is accepted, then
optimizer functions are also executed in a dynamic environment
in which COMPILER-LET bindings are visible.
The intent is that some macros might macroexpand into calls to
COMPILER-LET in which the body would the contain references to
macros which access the variables in the COMPILER-LET.
The initial value forms of the bindings, if any, are always
evaluated in a null lexical context, regardless of whether the
COMPILER-LET expression is being interpreted or compiled.
The initial value forms of the bindings, if any, are evaluated in
a dynamic context where the bindings of any lexically enclosing
COMPILER-LET are visible, and where dynamic execution-time
environment may or may not be visible.
Implementation Note: Permitting the execution-time dynamic
environment to be visible when initializing COMPILER-LET variables
is a concession to some interpreters which may have to do this in
order to keep the cost down. Where feasible, implementors should
try not to make the runtime environment visible.
Rationale:
This gives a consistent description of COMPILER-LET which separates
issues of intent from those of implementation in a way that makes it
possible for portable code to make serious use of it, and which does
not force gratuitous incompatibilities between interpreters and
compilers.
This description of COMPILER-LET can be implemented without undue
cost by all implementations. See "Cost to Implementors" for details.
Cost to Implementors:
Modest, but nontrivial in some implementations.
In compiled code, and in interpreters doing a one-time semantic
prepass, it should be fairly easy for COMPILER-LET to cause the
variables to get bound (using PROGV) during semantic analysis.
In interpreters which do not do a semantic-prepass, it is necessary
to fully macroexpand the body. Assuming the presence of a
SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
could look like:
(DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
(SETQ BINDINGS ;; Assure no non-atom bindings
(MAPCAR #'(LAMBDA (BINDING)
(IF (ATOM BINDING) (LIST BINDING) BINDING))
BINDINGS))
(PROGV (MAPCAR #'CAR BINDINGS)
(MAPCAR #'(LAMBDA (BINDING) (EVAL (CADR BINDING))) BINDINGS)
(SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))
This reduces the problem of writing a program capable of doing a
full macroexpansion. Many systems already have such a facility.
Pitman wrote such a facility in Cloe Runtime in order support
SYMBOL-MACROLET (before it was christened a special form); it was
about 750 lines of relatively straightforward, well-commented code.
Cost to Users:
Code currently depending on this feature is either non-existent or
already not portable (due to wide variation in implementation
strategy for COMPILER-LET).
Most users will probably be happy for any interpretation which offers
them a future shot at portability.
Some users have indicated they dislike interpreters which do a semantic
prepass, because they like to be able to dynamically redefine macros
while debugging.
Proposal (COMPILER-LET-CONFUSION:ELIMINATE):
Remove COMPILER-LET from the language.
Rationale:
Some people think that having one less special form would simplify the
language. The revised COMPILER-LET semantics, which require
COMPILER-LET to make special bindings which are only visible during
expansion of macros which appear lexically within its body, are
not shared by any other feature in the language, and require a
fairly complex implementation technique. There are other
constructs which are strictly lexical that can be readily used
to solve the same kinds of problems that COMPILER-LET is intended to
be used for.
Cost to Implementors:
Minimal. Implementations could continue to support COMPILER-LET as
an extension.
Cost to Users:
Code currently depending on this feature is either non-existent or
already not portable (due to wide variation in implementation
strategy for COMPILER-LET).
People who use COMPILER-LET would have to rewrite their programs to use
some other construct. As discussed above, most uses of COMPILER-LET
for communication between macros can be handled using MACROLET or
SYMBOL-MACROLET, though some perspicuity may be lost in the process.
Current Practice:
Some implementations have implemented the description in CLtL.
Users of those implementations (quite reasonably) can't figure how to
use COMPILER-LET and so don't use it much.
Some implementations whose interpreters include a preprocessor to
expand all macros have already implemented something similar to proposal
COMPILER-LET-CONFUSION:REPAIR. Users of such implementations
probably use COMPILER-LET somewhat more often since it has an
intelligible behavior, but their code is not portable since it relies
on behaviors which are either contrary to or not guaranteed by CLtL.
Benefits:
Either way, a potential area of incompatibility between compiled and
interpreted code would be eliminated.
Either way, a potential area of portability trouble would be very
drastically reduced (in the case of the REPAIR option) or eliminated
(in the case of the ELIMINATE option).
Discussion:
Pitman strongly favors COMPILER-LET-CONFUSION:REPAIR. He argues
against the idea of using MACROLET instead of COMPILER-LET, saying:
This is a little misleading because it's like saying you can
do without LET given that you have FLET. You can, but you lose some things
in the process:
Just as rewriting a LET using FLET might slow your computation, so too
a rewrite of COMPILER-LET using MACROLET might slow things down. However,
compilation speed is generally not weighted as heavily as execution speed
by many people, so the loss of speed here may not be as important.
Just as rewriting a LET using FLET might obscure the simplicity of your
intent, so too rewriting COMPILER-LET using MACROLET might obscure your
intent. You'd probably get used to recognizing idioms if you used it often
enough. Certainly this would be true if you didn't have LET. However,
COMPILER-LET is used less often, so not having it would mean that the
code you wrote instead would be much harder to read because people
wouldn't have the necessary familiarity with the idioms involved and so
wouldn't always understand them.
Sandra Loosemore responds:
The argument that using MACROLET is more inefficient than COMPILER-LET
is questionable. Both of the suggested implementation techniques for
COMPILER-LET involve considerable overhead.
If COMPILER-LET were not part of the language, people wouldn't think in
terms of rewriting COMPILER-LETs as MACROLETs; instead, they'd think of
how to use MACROLET in the first place to solve their problems. This
is what people who now use implementations with broken COMPILER-LETs
already do. Since MACROLET is now used much more frequently than
COMPILER-LET, that argues that people are much more familiar with
MACROLET idioms than COMPILER-LET idioms.
Also, note that the intent of the revised COMPILER-LET definition is
to make the binding only lexically visible within the body. Using
special binding for this purpose is troublesome. Both the MACROLET
and SYMBOL-MACROLET solutions are completely lexical and avoid all
the problems associated with special binding.
Glenn Burke thinks it needs to be emphasized that the code-walker
mentioned in the REPAIR proposal does not need to be portable. He
says:
The present wording makes it sound like a piece of cake to do with
portable code, when the reality is that a good fraction of CL cleanup
effort has involved the lack of capability of producing such a beast.
Without one or more of a number of proposals being accepted, a fully
correct portable code walker cannot be built, in my belief.
I object to the flippant attitude of just "presupposing" this
"trivial" function which "we know how to do".
We have considered a number of other options on this issue, including
a variety of proposals that would redefine COMPILER-LET to store
information about the variable bindings in the lexical environment, and
either having MACROEXPAND-1 make the special bindings or provide a
function which could be used to access them directly.
Kent Pitman says:
People have suggested that if it comes to making an incompatible change
on this one, it's probably better to just remove the feature and let
people continue to provide it compatibly where they think it's useful.
Even though I think the COMPILER-SYMBOL-VALUE thing is technically
doable, I find myself swayed by arguments that it's not the correct
avenue for us to pursue at this time.
David Moon says:
I think COMPILER-LET-CONFUSION:REPAIR should be split into four proposals.
First, one that gives the general framework for repairing but doesn't
say anything about how the interpreter implements COMPILER-LET, other
than to say that an additional proposal is needed to cover that. Then
three proposals for how the interpreter implements COMPILER-LET:
(1) The interpreter always does a "semantic pre-pass" like the compiler.
(2) The interpreter expands all macros inside COMPILER-LET before
evaluating any of the code inside COMPILER-LET.
(3) COMPILER-LET passes the variable bindings to MACROEXPAND-1
through the lexical environment, and the time when the interpreter
expands macros is not changed.
-------
∂23-Mar-89 1523 X3J13-mailer issue CONSTANT-COLLAPSING, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:22:35 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA12319; Thu, 23 Mar 89 13:55:55 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12724; Thu, 23 Mar 89 13:55:52 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232055.AA12724@defun.utah.edu>
Date: Thu, 23 Mar 89 13:55:51 MST
Subject: issue CONSTANT-COLLAPSING, version 6
To: x3j13@sail.stanford.edu
This issue has had some editorial changes made to it, to clarify the
terminology that it uses.
Forum: Compiler
Issue: CONSTANT-COLLAPSING
References: CLtL p. 78, 87
Issue CONSTANT-MODIFICATION
Issue CONSTANT-COMPILABLE-TYPES
Issue EQUAL-STRUCTURE
Issue QUOTE-SEMANTICS
Category: CHANGE
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 12 Dec 1988, Sandra Loosemore
V3, 03 Jan 1989, Sandra Loosemore
V4, 06 Jan 1989, Sandra Loosemore
V5, 11 Mar 1989, Sandra Loosemore
V6, 22 Mar 1989, Sandra Loosemore (comments from Moon)
Status: Ready for release
Problem Description:
CLtL states that an implementation is permitted to "collapse" or
coalesce constants appearing in code to be compiled if they are EQUAL.
The definition of EQUAL does not permit coalescing of more general
isomorphic data structures (such as arrays), which is often desirable.
This proposal deals only with changing the test which is used to
determine whether two constants may be coalesced. Issue
QUOTE-SEMANTICS deals with whether coalescing may be performed only by
COMPILE-FILE, or by COMPILE and EVAL as well. If proposal
QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE passes, then coalescing could be
performed on all constants.
This proposal uses the terms "source code", "compiled code", and
"similar as constants" that are defined in proposal
CONSTANT-COMPILABLE-TYPES:SPECIFY.
The term "coalesce" is defined as follows. Suppose A and B are two
objects used as quoted constants in the source code, and that A' and
B' are the corresponding objects in the compiled code. If A' and B'
are EQL but A and B were not EQL, then we say that A and B have been
coalesced by the compiler.
Proposal CONSTANT-COLLAPSING:GENERALIZE:
State that an implementation is permitted to coalesce constants
appearing in code to be compiled if and only if they are similar as
constants, unless the objects involved are of type SYMBOL, PACKAGE,
STRUCTURE, or STANDARD-OBJECT.
Rationale:
There is little reason why implementations should not be allowed to
perform more general collapsing of objects, since the arguments
against doing so also apply to collapsing of EQUAL objects, which
is already permitted. The arguments for coalescing of EQUAL data
structures (primarily space reduction) also apply to coalescing of
data structures that are equivalent under a more general coalescing
predicate.
Objects of type SYMBOL and PACKAGE cannot be coalesced because the fact
that they are named, interned objects means they are already as
coalesced as it is useful for them to be. Uninterned symbols could
perhaps be coalesced, but that was thought to be more dangerous than
useful. Objects of type STRUCTURE and STANDARD-OBJECT could be
coalesced if a "similar as a constant" predicate were defined for them;
it would be a generic function. Currently LOAD-OBJECTS only defines how
COMPILE-FILE and LOAD work together to construct an object in the
compiled code that is equivalent to the object in the source code,
and a different mechanism would have to be added to permit coalescence.
Current Practice:
Both PSL/PCLS and A-Lisp collapse isomorphic arrays and structures,
and certain other data types that are defined internally as structures
(RANDOM-STATEs, for example). Lucid Common Lisp also uses a more
general coalescing predicate than EQUAL.
Cost to implementors:
For implementations that currently coalesce based on EQUAL or that do
no coalescing, there is no associated implementation cost.
For implementations that currently coalesce things that this proposal
forbids them to coalesce (such as STRUCTUREs or uninterned symbols),
the implementation cost is probably small.
Cost to users:
Programs that depend on objects not being coalesced except when they
are EQUAL may break under this proposal. The only way one would be
able to detect that coalescing has taken place is if objects that were
not EQL in the source file become EQL after compilation; accessors on
the objects would return the same values regardless of whether or not
coalescing has taken place.
Benefits:
Collapsing of isomorphic arrays may lead to significant memory savings
in some applications.
Discussion:
This proposal depends heavily on issue CONSTANT-COMPILABLE-TYPES.
Some people believe that if the definition of EQUAL weren't "broken",
there wouldn't be any need for this proposal.
There is no inherent reason why the "coalescing predicate" must be the
same as the relationship used by the compiler/loader to construct
equivalent copies of objects of constants, but making the same rules
be applied in both situations simplifies the language somewhat.
-------
∂23-Mar-89 1521 X3J13-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 9
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:21:20 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA14332; Thu, 23 Mar 89 14:39:26 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12751; Thu, 23 Mar 89 14:39:23 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232139.AA12751@defun.utah.edu>
Date: Thu, 23 Mar 89 14:39:21 MST
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 9
To: x3j13@sail.stanford.edu
The part of this proposal that used to be item (3) has been moved to
issue EVAL-WHEN-NON-TOP-LEVEL. It now has a new item (3) dealing with
MACROLET semantics.
Please consider this issue carefully. It specifies some incompatible
changes to the treatment of macro functions, both for DEFMACRO and
MACROLET. The changes to DEFMACRO are necessary for compatibility
with issue EVAL-WHEN-NON-TOP-LEVEL. The changes to MACROLET are seen
as desirable for compatibility with the changes to DEFMACRO.
Forum: Compiler
Issue: DEFINING-MACROS-NON-TOP-LEVEL
References: CLtL p. 66-70, 114, 143
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue COMPILER-LET-CONFUSION
Category: CLARIFICATION, ENHANCEMENT, CHANGE
Edit History: 6-May-88, V1 by Sandra Loosemore
9-Jun-88, V2 by Sandra Loosemore
12-Sep-88, V3 by Sandra Loosemore (fix garbled section 4)
21-Sep-88, V4 by Sandra Loosemore (clarify section 5)
16-Dec-88, V5 by Sandra Loosemore (major restructuring)
31-Dec-88, V6 by Sandra Loosemore (wording clarifications)
07-Jan-89, V7 by Sandra Loosemore (add example)
09-Mar-89, V8 by Sandra Loosemore (more restructuring)
22-Mar-89, V9 by Sandra Loosemore (add MACROLET stuff)
Status: Ready for release
Problem Description:
CLtL leaves the interpretation of defining forms such as DEFMACRO and
DEFVAR that appear in other than top-level locations unclear.
On page 66, it is stated: "It is not illegal to use these forms at
other than top level, but whether it is meaningful to do so depends on
context. Compilers, for example, may not recognize these forms
properly in other than top-level contexts". At least one implementation
has interpreted this to mean that it is permissible to simply refuse
to compile defining macros that do not appear at top-level.
A further problem is that CLtL p. 145 states that macro functions are
always defined in the null lexical environment. These semantics would
require it to be a special form, not a macro, since there is no
possible macro expansion that has equivalent semantics under the
processing model presented in issue EVAL-WHEN-NON-TOP-LEVEL. Under
that model, it ought to be possible for DEFMACRO to be implemented as
expanding into an EVAL-WHEN. Furthermore, the macro function should
appear in a for-evaluation position in the expansion, such as
(function (lambda ...)).
Proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW:
(1) Remove the language from p. 66 of CLtL quoted above. Clarify that
while defining macros normally appear at top level, it is meaningful
to place them in non-top-level contexts and that the compiler must
handle them properly in all situations. However, the compile-time side
effects described in issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
only take place when the defining macros appear at top-level.
(2) Remove the language from p. 145 of CLtL referenced above. Clarify
that all defining macros which create functional objects (including
DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
DEFSETF, as well as DEFUN) must ensure that those functions are
defined in the lexical environment in which the defining form appears.
(3) Change the description of MACROLET to indicate that the macro
functions it creates are defined in the lexical environment in which
the MACROLET form appears, and not the null lexical environment.
State that declarations and MACROLET and SYMBOL-MACROLET definitions
affect the local macro definitions in a MACROLET, but that the
consequences are undefined if the local macro definitions reference
any local variable or function bindings that are visible in that
lexical environment.
Rationale:
Items (1) and (2) make the rules for when defining macros cause
compile-time side effects to be exactly the same as the rules for when
(EVAL-WHEN (COMPILE) ...) causes compile-time evaluation. This
provides a simple implementation technique.
Item (3) makes the handling of MACROLET macro definitions consistent
with DEFMACRO macro definitions.
Current Practice:
Most implementations do allow defining macros in non-top-level places.
However, the rules for when they cause compile-time side-effects are
not always the same as those for EVAL-WHEN. This is the case in
Lucid Common Lisp, for example.
Lucid evaluates DEFMACRO macro functions in the lexical environment
in which the DEFMACRO appears, but always evaluates MACROLET macro
functions in the null lexical environment.
Cost to implementors:
Implementations that currently don't compile defining macros correctly
when they appear at non-top-level will have to be changed.
There will also be changes required to support compile-time definition
of functions in a non-null lexical environment. These changes
are required to support defining macros such as DEFINE-SETF-METHOD
that require functional objects to be created at compile-time, as well
as to support the changes to DEFMACRO and MACROLET. (Note that even
though defining macros cause compile-time evaluation only at
top-level, top-levelness does not necessarily imply a null lexical
environment under proposal EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL.)
Cost to users:
The changes to DEFMACRO and the other defining macros probably will
cause few problems for users. Since CLtL didn't require non-top-level
defining macros to be meaningful, assigning them a meaning is a
compatible extension.
The changes to MACROLET may cause problems for users who have assumed
that, within local macro definitions, global function and variable
definitions are not shadowed by local function and variable bindings.
Code-walking programs will also have to be changed to reflect the new
semantics (see issue SYNTACTIC-ENVIRONMENT-ACCESS).
Benefits:
The notion of defining macros as being somehow special when they
appear at top-level is removed, since their behavior can be explained
using EVAL-WHEN as a primitive. Allowing defining macros to appear
anywhere instead of restricting them to certain positions results in a
cleaner language design.
Discussion:
This proposal is consistent with the behavior specified in proposal
EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL. In particular, if the compile
time side-effects for defining macros specified in proposal
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY are implemented using
EVAL-WHEN, the "right" compiler behavior for defining macros at
non-top-level will happen automatically.
The problems with compile-time definition of functions in a non-null
environment could be avoided by modifying proposal
DEFINING-MACROS-NON-TOP-LEVEL to remove the special treatment for
MACROLET, SYMBOL-MACROLET, and LOCALLY.
-------
∂23-Mar-89 1522 X3J13-mailer issue QUOTE-SEMANTICS, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:21:49 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA14563; Thu, 23 Mar 89 14:49:18 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12765; Thu, 23 Mar 89 14:49:15 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232149.AA12765@defun.utah.edu>
Date: Thu, 23 Mar 89 14:49:14 MST
Subject: issue QUOTE-SEMANTICS, version 3
To: x3j13@sail.stanford.edu
I have made some clarifications to the language in this issue, and
expanded the Cost to Implementors and Discussion sections.
Forum: Compiler
Issue: QUOTE-SEMANTICS
Subsumes: Issue QUOTE-MAY-COPY
References: CLtL p. 55, 78, 86, 143
Issue CONSTANT-COLLAPSING
Issue CONSTANT-COMPILABLE-TYPES
Issue CONSTANT-CIRCULAR-COMPILATION
Category: CLARIFICATION
Edit History: V1, 22 Jan 1989, Sandra Loosemore
V2, 13 Mar 1989, Sandra Loosemore (discussion)
V3, 22 Mar 1989, Sandra Loosemore (suggestions from Moon)
Status: Ready for release
Problem Description:
Is it permissible for COMPILE and EVAL to coalesce or copy constants?
Are there constraints upon what kinds of objects may appear as
constants in code processed by COMPILE or EVAL, similar to those for
COMPILE-FILE?
CLtL p86 states that (QUOTE <x>) simply returns <x>. On p55 it is
mentioned that the only self-evaluating forms that may be copied are
numbers or characters. It is also stated that an implementation is
permitted to collapse (or coalesce) EQUAL constants "appearing in code
to be compiled" (p78), which is defined to mean self-evaluating forms
or objects contained in a QUOTE form (without reference to whether the
form is processed by EVAL, COMPILE, or COMPILE-FILE).
Because of its nature as a file processor, COMPILE-FILE generally must
cause copies of constants to be constructed when the compiled code is
loaded. In a number of existing Lisp implementations, COMPILE also
causes constant objects to be copied and/or coalesced. There is also
at least one implementation where constants are copied by EVAL in some
circumstances.
In the proposals that follow, "copying" is used to mean the process of
constructing an object that is "similar as a constant" (as defined in
proposal CONSTANT-COMPILABLE-TYPES:SPECIFY), but not necessarily EQL,
to the original.
The term "coalescing" is defined in the writeup for issue
CONSTANT-COLLAPSING.
Proposal QUOTE-SEMANTICS:NO-COPYING:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is not permitted; the resulting program
must reference objects that are EQL to the corresponding objects in
the source code. The constraints on what kinds of objects may appear
as constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.
Rationale:
This proposal is consistent with what many people think of as the
"traditional" semantics for QUOTE. It gives users maximum flexibility
about what kinds of objects may appear as constants.
Proposal QUOTE-SEMANTICS:COPYING-ALLOWED-BUT-NO-CONSTRAINTS:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted. Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime. Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.
Any object may validly appear as a constant in code processed by EVAL
or COMPILE. The constraints on what kinds of objects may appear as
constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE. For data
types where proposal CONSTANT-COMPILABLE-TYPES:SPECIFY does not define
the notion of "similar as a constant", an implementation is permitted
to copy objects of that type only if it has extended "similar as a
constant" to include that type.
Rationale:
This proposal is the most consistent with the semantics stated in CLtL.
It gives users maximum flexibility about what kinds of objects may
appear as constants.
Allowing constants to be coalesced or copied has advantages for
memory management; for example, constants can be copied to read-only
memory that does not need to be garbage-collected.
Proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted. Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime. Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.
The constraints on what kinds of objects may appear as constants
(described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply to EVAL and COMPILE as well as to
COMPILE-FILE.
Rationale:
This makes the rules for handling of constants consistent between
EVAL, COMPILE, and COMPILE-FILE. It gives implementors maximum
flexibility in handling constants in EVAL and COMPILE.
Allowing constants to be coalesced or copied has advantages for
memory management; for example, constants can be copied to read-only
memory that does not need to be garbage-collected.
Current Practice:
Implementations in which COMPILE attempts to copy all constants
include PSL/PCLS, Utah Common Lisp, and Kyoto Common Lisp. UCL and
KCL both implement COMPILE effectively as a combination of
COMPILE-FILE and LOAD.
In Lucid Common Lisp, constants are not normally copied by COMPILE,
but since COMPILE does coalesce constants, it may cause QUOTE to
return an object which is not EQL to the object which appeared in the
source code.
Symbolics Genera has COMPILE copy list, string, non-displaced array,
and (I-Machine only) closure constants, but Moon says he thinks this
is wrong.
There is known to be at least one implementation where expanding the
DEFUN macro causes all constants in the body of the function to be
copied.
Cost to implementors:
Proposal NO-COPYING would involve a significant cost in those
implementations where constants are now copied or coalesced by EVAL
and COMPILE. The aspect that is likely to cause the most problems is
that, in some implementations, the garbage collector assumes that
constants referenced in compiled code have been copied to read-only
storage and do not need to be scanned or relocated. Changing this
would require major changes to the internal representation of
functions, memory management strategy, and/or the implementation of
COMPILE.
Some implementations would also require substantial changes to support
proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS. Implementations that
would have garbage collection problems under proposal NO-COPYING would
have the same problems under COPYING-ALLOWED-BUT-NO-CONSTRAINTS,
unless they can define a copying behavior that will correctly handle
objects of all possible datatypes.
Proposal SAME-AS-COMPILE-FILE has no adoption cost above what is
required to support issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION.
Cost to users:
Proposals COPYING-ALLOWED-BUT-NO-CONSTRAINTS and SAME-AS-COMPILE-FILE
may break some existing programs that assume constants in code
processed by EVAL or COMPILE are always EQL to the corresponding
objects in the source code. Proposal SAME-AS-COMPILE-FILE may also
break existing programs that depend on referencing "undumpable"
constants in code processed by EVAL or COMPILE. In both cases,
however, the behavior is already nonportable. Both proposals would
permit implementations in which these programs now work to continue to
provide their existing behavior.
Benefits:
The semantics of QUOTE are clarified.
Discussion:
This issue subsumes issue QUOTE-MAY-COPY, which caused a very lengthy
debate on the cl-compiler mailing list.
This issue relates to conformance requirements. Accepting either of
proposals NO-COPYING or COPYING-ALLOWED-BUT-NO-CONSTRAINTS would mean
that not all conforming programs could be compiled with COMPILE-FILE.
Some people may find this disturbing, particularly since one of the
goals of Common Lisp has been to try to eliminate differences in
semantics between compiled and interpreted code.
Loosemore supports proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE,
since it requires essentially no conversion cost for implementors and
does not break any user programs that are not already nonportable.
JonL White says:
Since we have already passed the proposal that permits constants to
be "read-only" -- it is an error to modify them -- and have already
passed the proposal that allows access to updateable structures --
LOAD-TIME-EVAL -- then there is no excuse for being overly concerned
with the storage address of quoted data. People who have mistakenly
used structured constants as updatable data should convert over to
either LOAD-TIME-EVAL or DEFPARAMETER.
Kent Pitman says:
The problem is that a lot of copying advocates have been going around
trying to use "the need for copying" as leverage for restricting
the set of things which I may quote. My view is that it is my write [sic]
to quote whatever I want, and it's up to the person who thinks they
can do something fun with copying to not get themselves in deeper than
they can handle.
Jeff Dalton says:
I would agree [with Pitman's remarks] too. My only quibble is that
it's not just "the need for copying" that's used a lever.
"Consistency with file compilation" is also being used as a lever.
UCL implements COMPILE by dumping and loading a temporary file using
the same mechanisms as COMPILE-FILE and LOAD. Leigh Stoller (one of
the UCL compiler implementors) says that, even if this implementation
technique is disallowed by the outcome of this issue, they would
rather be nonconforming than change the implementation of COMPILE. In
addition to the change being a lot of work, he says he thinks that
making COMPILE-FILE and COMPILE different would be "really dumb", and
that having different conformance requirements for compiled and
interpreted code would just encourage people to write programs that
can't be compiled correctly.
-------
∂23-Mar-89 1523 X3J13-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:23:21 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA12090; Thu, 23 Mar 89 13:49:30 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12718; Thu, 23 Mar 89 13:49:27 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232049.AA12718@defun.utah.edu>
Date: Thu, 23 Mar 89 13:49:25 MST
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 8
To: x3j13@sail.stanford.edu
Changes to this issue since version 7 (distributed last week) include:
- all references to EQ have been changed to EQL.
- error terminology has (hopefully) been fixed.
- added note about handling of uninterned symbols.
Forum: Compiler
Issue: CONSTANT-CIRCULAR-COMPILATION
References: Issue CONSTANT-COLLAPSING
Issue QUOTE-SEMANTICS
Category: CLARIFICATION, ADDITION
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 14 Nov 1988, Cris Perdue
V3, 12 Dec 1988, Sandra Loosemore (merge versions 1 and 2)
V4, 03 Jan 1989, Sandra Loosemore (add PRESERVE-SHARING-ONLY)
V5, 06 Jan 1989, Sandra Loosemore (minor wording changes)
V6, 08 Feb 1989, Sandra Loosemore (replace FLAG with YES)
V7, 11 Mar 1989, Sandra Loosemore (error terminology)
V8, 18 Mar 1989, Sandra Loosemore (changes per Moon, Masinter)
Status: Ready for release
Problem Description:
CLtL does not specify whether constants containing circular or
recursive references may be compiled. It is also not clear whether
the compiler must preserve sharing of EQL substructures; that is, whether
subobjects that are EQL in the source code must remain EQL after being
compiled.
The proposals below apply to constants appearing in a file compiled by
COMPILE-FILE. If proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE
passes, then the same constraints would apply to all constants. The
minimal scope over which sharing would be required to be detected is
over a single call to EVAL or COMPILE.
In the proposals that follow, "preserving EQLness" means that
subobjects that are EQL in the source code must remain EQL after being
compiled; that is, things don't get "less EQL" after compilation.
(Note that coalescing of constants implies that things may get "more
EQL".)
Proposal CONSTANT-CIRCULAR-COMPILATION:NO
State that conforming programs must not contain circular objects
appearing as constants to be compiled. The consequences of compiling
a program containing such an object with COMPILE-FILE and/or LOADing
the output produced by COMPILE-FILE for such a program [and, if we
accept proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE, compiling it
with COMPILE or evaluating it interpretively] are undefined.
State that the compiler is not required to preserve EQLness of
substructures.
Rationale:
This proposal would not require any existing implementation to change.
Disallowing portable programs from containing circular constants
allows compiled file loaders to use somewhat simpler implementation
strategies (for example, to build constants in a strict bottom-up
fashion).
Proposal CONSTANT-CIRCULAR-COMPILATION:PRESERVE-SHARING-ONLY
State that conforming programs must not contain circular objects
appearing as constants to be compiled. The consequences of compiling
a program containing such an object with COMPILE-FILE and/or LOADing
the output produced by COMPILE-FILE for such a program [and, if we
accept proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE, compiling it
with COMPILE or evaluating it interpretively] are undefined.
State that the compiler is required to preserve EQLness of
substructures within a file compiled with COMPILE-FILE.
Rationale:
Disallowing portable programs from containing circular constants
allows compiled file loaders to use somewhat simpler implementation
strategies (for example, to build constants in a strict bottom-up
fashion).
Some programs (such as PCL) have come to depend on COMPILE-FILE
preserving the EQLness of uninterned symbols, and it is cleaner
to require sharing to be preserved in general instead of making
symbols be a special case. Requiring sharing to be preserved still
allows loaders to build constants bottom-up.
Proposal CONSTANT-CIRCULAR-COMPILATION:YES
State that objects containing circular references may legitimately
appear as constants to be compiled. State that the compiler is
required to preserve EQLness of substructures within a file compiled
with COMPILE-FILE.
Rationale:
Users seem to expect this functionality, and some implementations
already provide it.
Current Practice:
A-Lisp preserves EQLness of substructures (since it makes an effort to
collapse isomorphic structures) but signals an error if an attempt is
made to compile a circular constant. PSL and Utah Common Lisp both
get stuck in an infinite loop if an attempt is made to compile a
reentrant structure. The TI Explorer compiler is able to reproduce
recursive lists and arrays, but currently hangs in a loop on a
circular list. Neither the Explorer nor Symbolics Genera 7.x detects
EQLness of list CDRs. Lucid handles circular constants correctly.
Franz uses a flag to control whether or not to attempt to detect
circular constants. KCL handles circular structures, but only detects
sharing of top-level structure (it does not traverse constants to look
for shared substructure).
Cost to implementors:
We know of no implementation that would have to change under proposal
NO.
For proposal YES, some implementations would require sweeping
changes; in some cases a completely different dumper/loader strategy
would have to be implemented.
The cost of proposal PRESERVE-SHARING-ONLY would fall somewhere in
between.
Cost to users:
The situation now is that programs which depend upon circularity or
sharing of substructure being preserved by the compiler are already
nonportable. Proposal NO simply formalizes the status quo. Proposal
YES would offer users functionality that is currently not portable.
Portable CommonLoops reportedly requires EQLness of uninterned symbols
to be preserved across a file, and would break under proposal NO.
According to Cris Perdue:
I am told that support for PCL requires the kinds of guarantees about
uninterned symbols [that say EQLness will be preserved]. Jim Kempf
here at Sun tells me he believes that this is true. John Foderaro
said that Franz made their compiler give this behavior in order to
support PCL.
Jim Kempf says he believes that certain GENSYMs appear in multiple
pieces of initialization code across a file in PCL, and the
initialization code only works if symbols EQ at compile time map to
symbols that are EQ at load time.
Benefits:
An area of ambiguity in the language is removed.
Discussion:
The issue of compiler speed is largely a red herring on this issue;
the overhead of detecting circularities is generally quite small. The
main question is whether we should require some implementations to
completely redo their compiler/loader interface in order to support
circular constants.
It has been argued that any "serious" implementation will support
circular constants anyway, because of customer demand. However, since
there appears to be only one implementation (Lucid) that now
implements proposal YES in its full generality, perhaps the demand for
this feature is not really all that strong.
Earlier drafts of this writeup contained a proposal FLAG which would
have added a variable *COMPILE-CIRCLE*, similar to *PRINT-CIRCLE*.
However, there were unresolved problems about what would happen if the
value of this variable were altered within the file being compiled,
and it was generally agreed that this proposal didn't have any
particular advantages over proposal YES and just introduced
unnecessary hairiness.
Since it is usually fairly simple to detect circular constants,
Loosemore would support an amendment to proposals NO and
PRESERVE-SHARING-ONLY to change the word "undefined" to "unspecified",
adding:
Implementations must either correctly handle the circular reference
or signal an error.
This is similar to the language which is already used in proposal
CONSTANT-COMPILABLE-TYPES:SPECIFY.
-------
∂23-Mar-89 1537 X3J13-mailer **DRAFT** Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4)
Received: from YUKON.SCRC.Symbolics.COM (SCRC-YUKON.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:36:24 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 441574; Thu 23-Mar-89 16:01:03 EST
Date: Thu, 23 Mar 89 15:57 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323155755.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<
Bring your comments to the meeting.
For those on CL-Cleanup, I modified this version only very slightly
to accomodate out-and-out typos. I have not made any new conceptual
strides on this pass.
All should see of CL-Cleanup discussion at end.
-kmp
-----
Issue: PATHNAME-SUBDIRECTORY-LIST
References: Pathnames (pp410-413), MAKE-PATHNAME (p416),
PATHNAME-DIRECTORY (p417)
Category: CHANGE
Edit history: 18-Jun-87, Version 1 by Ghenis.pasa@Xerox.COM
05-Jul-88, Version 2 by Pitman (major revision)
28-Dec-88, Version 3 by Pitman (merge discussion)
23-Mar-89, Version 4 by Pitman ([hopefully] just fix typos)
Status: For Internal Discussion
Related-Issues: PATHNAME-COMPONENT-CASE
Problem Description:
It is impossible to write portable code that can produce a pathname
in a subdirectory of a hierarchical file system. This defeats much of
the purpose of having an abstraction like pathname.
According to CLtL, only a string is a portable filler of the directory
slot, but in order to denote a subdirectory, the use of separators (such
as dots, slashes, or backslashes) would be necessary. The very fact that
such syntax varies from host to host means that although the
representation might be "portable", the code using that representation
is not portable.
This problem is even worse for programs running on machines on a network
that can retrieve files from multiple hosts, each using a different OS
and thus a different subdirectory delimiter.
Related problems:
- In some implementations "FOO.BAR" might denote the "BAR" subdirectory
of "FOO" while in other implementations it might be a top-level
directory (because "." is not a subdirectory separator). To be safe,
portable programs must avoid all potential separators.
- Even in implementations where "." is the separator, "FOO.BAR" may be
recognized by some to mean the "BAR" subdirectory of "FOO" and by others
to mean `a seven letter directory with "." being a superquoted part of
its name'.
- In fact, CLtL does not even say for toplevel directories whether the
directory delimiters are a part. eg, is "foo" or "/foo" the directory
filler for a unix pathname "/foo/bar.lisp". Similarly, is "[FOO]" or
"FOO" the directory filler for a VMS pathname "[FOO]ME.LSP"?
Proposal (PATHNAME-SUBDIRECTORY-LIST:NEW-REPRESENTATION)
Allow a list to be a filler of a pathname. The car of the list may be either
of the symbols :ABSOLUTE or :RELATIVE.
If the car of the list is :RELATIVE, the rest of the list is the
implementation-dependent result of PARSE-NAMESTRING for file systems which
have relative pathnames. Unless some other proposal is submitted to clarify
the behavior of relative pathnames in merging, etc. that behavior is left
undefined.
If the car of the list is :ABSOLUTE, the rest of the list is a list of
strings each naming a single level of directory structure. The strings
should contain only the directory names themselves -- no separator
characters.
The spec (:ABSOLUTE) represents the root directory.
Clarify that if a string is used as a filler of a directory field in a
pathname, it should be the unadorned name of a toplevel directory.
Specifying a string, str, is equivalent to specifying the list
(:ABSOLUTE str).
In place of a string, at any point in the list, keyword symbols may occur
to deal with special file notations. The following symbols have standard
meanings; they may not be meaningful for all operating systems, and are
intended for use only on those operating systems where they have meaning:
:WILD - Wildcard match of one level of directory structure.
:WILD-INFERIORS - Wildcard match of any number of directory levels.
:UP - Go upward in directory structure (syntactic).
:BACK - Go upward in directory structure (semantic).
The difference between up and back is that if there is a directory
(:ABSOLUTE "X" "Y" "Z")
linked to
(:ABSOLUTE "A" "B" "C")
and there also exist directories
(:ABSOLUTE "A" "B" "Q")
(:ABSOLUTE "X" "Y" "Q")
then
(:ABSOLUTE "X" "Y" "Z" :BACK "Q")
designates
(:ABSOLUTE "A" "B" "Q")
while
(:ABSOLUTE "X" "Y" "Z" :UP "Q")
designates
(:ABSOLUTE "X" "Y" "Q")
Test Case:
(PATHNAME-DIRECTORY (PARSE-NAMESTRING "[FOO.BAR]BAZ.LSP")) ;on VMS
=> (:ABSOLUTE "FOO" "BAR")
(PATHNAME-DIRECTORY (PARSE-NAMESTRING "/foo/bar/baz.lisp")) ;on Unix
=> (:ABSOLUTE "foo" "bar")
or (:ABSOLUTE "FOO" "BAR")
If PATHNAME-COMPONENT-CASE:CANONICALIZE passes, only the 2nd return value.
(PATHNAME-DIRECTORY (PARSE-NAMESTRING ">foo>**>bar>baz.lisp")) ;on LispM
=> (:ABSOLUTE "FOO" :WILD-INFERIORS "BAR")
(PATHNAME-DIRECTORY (PARSE-NAMESTRING ">foo>*>bar>baz.lisp")) ;on LispM
=> (:ABSOLUTE "FOO" :WILD "BAR")
Rationale:
This would allow programs to usefully deal with hierarchical file systems,
which are by far the most common file system type.
Current Practice:
Symbolics Genera implements something very similar to this. The main
differences are:
- In Genera, there is no :ABSOLUTE keyword at the head of the list.
This has been shown to cause some problems in dealing with root
directories. Genera represents the root directory by a keyword
symbol (rather than a list) because the list representation
was not adequately general.
- Genera represents Unix ".." as :UP. Its treatment of :UP is compatible
with this proposal, but Unix ".." is more properly represented by :BACK.
Cost to Implementors:
In principle, nothing about the implementation needs to change except
the treatment of the directory field by MAKE-PATHNAME and
PATHNAME-DIRECTORY. The internal representation can otherwise be left
as-is if necessary.
For implementations that choose to rationalize this representation
throughout their internals and any other implementation-specific
accessors, the cost will be necessarily higher.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Serious portability problems would continue to occur. Programmers would be
driven to the use of implementation-specific facilities because the need
for this is frequently impossible to ignore.
Benefits:
The serious costs of non-adoption would be avoided.
Aesthetics:
This representation of hierarchical pathnames is easy to use and quite
general. Users will probably see this as an improvement in the aesthetics.
Discussion:
This issue was raised a while back but no one was fond of the particular
proposal that was submitted. This is an attempt to revive the issue.
The original proposal, to add a :SUBDIRECTORIES field to a pathname, was
discarded because it imposed an unnatural distinction between a toplevel
directory and its subdirectories. Pitman's guess is the the idea was to
try to make it a compatible change, but since most programmers will
probably want to change from implementation-specific primitives to portable
ones anyway, that's probably not such a big deal. Also, there might have
been some programs which thought the change was compatible and ended up
ignoring important information (the :SUBDIRECTORIES field). Pitman thought
it would be better if people just accepted the cost of an incompatible
change in order to get something really pretty as a result.
This issue used to address the issue of relative pathnames (pathnames
relative to some default which is separately maintained). Pitman removed
this issue for now in order to simplify things. He feels the issue should
be resubmitted under separate cover so that it can be discussed separately.
------
Summary of discussion on CL-Cleanup:
Moon wondered if functions like Symbolics' DIRECTORY-PATHNAME-AS-FILE
and PATHNAME-AS-DIRECTORY should be included either here or in
another issue. (The conversion between the name of a directory
and the directory component of a file inferior to that directory is
system-dependent, for example TOPS-20 appends a type field and Unix
does not. Also in some systems the root directory has a name and
in others it doesn't. Of course these functions signal an error in
non-hierarchical file systems.
Moon doesn't think :UP and :BACK are meaningful anywhere except
immediately after :RELATIVE, although he concedes Unix disagrees
with him. He suggests that if they were only allowed immediately
after :RELATIVE, you wouldn't need two of them. He also doesn't
think that MERGE-PATHNAMES should ever look at what files/directories
actually exist in the file system, which makes me opposed to the
existence of the one that you have called syntactic. He asks ``is
this really something we need, or will TRUENAME do the job?''
JLM replies (to Moon's query) that if you're trying to create a
filename to be used for output, it might not exist yet
(hence TRUENAME would signal an error), but there might
be various funny links in its directory path you would like to
traverse. Presumably you could use PROBE-FILE on some part of the
name (perhaps recursively down through the super-directories), then
merge in the remaining part, but that seems enough error-prone to be
worth hiding.
Aaron Larson has a competing or related proposal he wants to present
on this issue. I didn't attempt to summarize it here because it was
enough different from this discussion to raise presentational
confusion. My attempt here was mainly to get these thoughts on the
table -- not to preempt what he has to say. Hopefully he'll still
present his views separately.
∂23-Mar-89 1552 X3J13-mailer Issue: PATHNAME-COMPONENT-VALUE (version 1)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:51:29 PST
Received: from pitney-bowes ([192.9.200.50]) by heavens-gate.lucid.com id AA03604g; Thu, 23 Mar 89 13:25:02 PST
Received: by pitney-bowes id AA26521g; Thu, 23 Mar 89 13:23:24 PST
Date: Thu, 23 Mar 89 13:23:24 PST
From: Jim McDonald <jlm@lucid.com>
Message-Id: <8903232123.AA26521@pitney-bowes>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: X3J13@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Tue, 21 Mar 89 17:52 EST <19890321225242.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-COMPONENT-VALUE (version 1)
Food for thought:
An interesting alternative that was just suggested to me would split
the type PATHNAME into something like PATHNAME and PATHNAME-TEMPLATE.
OPEN, TRUENAME, and friends would accept only PATHNAME arguments,
and DIRECTORY would accept only PATHNAME-TEMPLATE arguments.
(DIRECTORY would return a list of PATHNAME's.)
This would perhaps enhance our ability to stabilize the syntax and
semantics of PATHNAME much more rigidly, and leave open room for
experimentation with PATHNAME-TEMPLATE, where there seems to be more
need for it.
The basic idea is that a pathname would specify at most one file (it
could be bogus), whereas PATHNAME-TEMPLATE would specify a set of
files.
jlm
∂23-Mar-89 1527 X3J13-mailer issue DEFINE-OPTIMIZER, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:26:04 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA13550; Thu, 23 Mar 89 14:18:32 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12741; Thu, 23 Mar 89 14:18:28 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232118.AA12741@defun.utah.edu>
Date: Thu, 23 Mar 89 14:18:27 MST
Subject: issue DEFINE-OPTIMIZER, version 6
To: x3j13@sail.stanford.edu
There have been a number of small changes made to this writeup.
- The description of DEFINE-OPTIMIZER now says that the optimizer should
return only one value.
- The relationship to INLINE/NOTINLINE declarations has been clarified.
- There have been some minor clarifications to wording.
- The discussion section has been expanded.
Forum: Compiler
Issue: DEFINE-OPTIMIZER
References: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Category: ADDITION
Edit history: 28-Sep-88, Version 1 by Pitman
10-Mar-89, Version 2 by Pitman (clarifications, new example),
10-Mar-89, Version 3 by Pitman & Loosemore
11-Mar-89, Version 4 by Pitman
13-Mar-89, Version 5 by Loosemore (discussion)
22-Mar-89, Version 6 by Loosemore (more discussion)
Status: Ready for release
Problem Description:
Often a general functional interface could be bypassed given explicit
knowledge of the arguments passed. This may happen when the arguments
are constant (or otherwise inferrable), an argument type is known (eg,
due to use of THE or DECLARE), or when some particular pattern of
optional, rest or keyword arguments is apparent.
Most implementations provide internally for optimization of generalized
function call interfaces to more specialized ones, but such an
optimization facility is not provided to Common Lisp users.
The absence of this facility in a portable fashion means that some
CL programs run slower than they need to in some implementations, or
else that some operators that should be implemented as functions end
up getting implemented as macros to assure needed efficiency.
Proposal (DEFINE-OPTIMIZER:NEW-FACILITY):
Introduce a facility for declaring compiler optimizations.
DEFINE-OPTIMIZER name arglist {declaration}* {form}* [Macro]
Defines a compiler optimizer for a function named NAME. The ARGLIST,
DECLARATIONS, and FORMS are treated exactly like the arglist,
declarations, and forms in a DEFMACRO. (The arglist may include
&ENVIRONMENT and &WHOLE.)
The argument NAME must name a function which has been previously
defined. The effects of defining an optimizer for a locally or
globally defined macro, a locally defined function, or a special
form are undefined.
When the optimizer is invoked, the forms are executed in the context
of bindings specified by the arglist as an implicit PROGN. The
optimizer should return a form which is preferable to evaluate instead
of the indicated call, or NIL to decline to optimize. If an optimizer
wishes to optimize into a form whose result is NIL, it should return
(QUOTE NIL). The resulting form should be careful to preserve the
semantics (including order-of-evaluation) of the original function
call.
If a call to DEFINE-OPTIMIZER appears at top-level in a file
being processed by the file compiler, it also makes the optimizer
known at compile-time (similar to the way DEFMACRO makes a macro
definition known to the compiler).
OPTIMIZE-EXPRESSION-1 form env [Function]
Similar to MACROEXPAND-1. Invokes the optimizers for the top level of
FORM, but does not iterate on the result. Returns two values:
RESULT and CHANGED-P.
Note: If an optimizer declines to optimize,
OPTIMIZE-EXPRESSION-1 hides the fact by returning FORM,NIL
rather than NIL,NIL.
OPTIMIZE-EXPRESSION form env [Function]
Iterates calling OPTIMIZE-EXPRESSION-1 until the CHANGED-P result
is NIL. Two values are returned: RESULT and CHANGED-P.
An implementation must save optimizer definitions created by
DEFINE-OPTIMIZER in case OPTIMIZE-EXPRESSION is attempted, but is
not actually required to call OPTIMIZE-EXPRESSION itself. Interpreters,
for example, may choose to just call the unoptimized form.
Special forms such as FLET and MACROLET that create local functional
definitions shadow not only functions and their SETF methods,
but also their optimizers. No portable facility is provided for creating
locally defined optimizers.
The effect of defining optimizations for functions in the LISP package
is not defined. (In some implementations, this would clobber or conflict
with existing advice that may be of higher quality.)
The editor is advised that a non-binding style note such as the
following would also be appropriate:
In general, it is poor style for a programmer to define optimizers for
functions that he does not maintain. This is because the correct
implementation of an optimizer for a function usually depends on an
understanding of the internals of that function. As such, a function
definition and any optimizers should be maintained as a unit so that
they can changes in either can be synchronized as appropriate with the
other.
If a function that has an optimizer function is declared INLINE,
the optimizer has precedence. If a function that has an optimizer
function is declared NOTINLINE, the application of the optimizer
function by OPTIMIZE-EXPRESSION and OPTIMIZE-EXPRESSION-1 is
inhibited.
Example:
;; These examples are taken literally from the Macsyma sources,
;; modified only to change DEFOPT to DEFINE-OPTIMIZER. The comments
;; were specially written for the X3J13 audience.
;; M+ is adds a Macsyma expression to another Macsyma expression.
;; The Macsyma internal representation for the sum of X and Y is
;; ((MPLUS) X Y). A all the real work is done by SIMPLIFY, which
;; reduces the expression as needed necessary. However, SIMPLIFY
;; is very complicated, and considerable speed can be gained by
;; entering it at specific known places.
(DEFUN M+ (&REST TERMS)
(PROTECT-&REST-VARIABLE TERMS)
(SIMPLIFY `((MPLUS) ,@TERMS)))
(DEFINE-OPTIMIZER M+ (&REST TERMS)
(COND ((= (LENGTH TERMS) 2) `(ADD2* ,@TERMS))
(T `(ADDN (LIST ,@TERMS) NIL))))
;; M- negates a Macsyma expression, or substracts two Macsyma
;; expressions. Once you figure out which of the two operations is
;; to be done, the problem is similar to that of M+ above. However,
;; often the decision can be made at compile time. In this case,
;; INLINE functions would have worked ok, except that not all
;; implementations do inlining, and even those that do may fail to
;; recognize that EXP2 being NIL means that a test can be eliminated
;; or dead code can be eliminated. Using optimizers is far more
;; likely to be useful in practice.
(DEFUN M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
(M--INTERNAL-NEGATE EXP1)
(M--INTERNAL-SUBTRACT EXP1 EXP2)))
(DEFINE-OPTIMIZER M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
`(M--INTERNAL-NEGATE ,EXP1)
`(M--INTERNAL-SUBTRACT ,EXP1 ,EXP2)))
Rationale:
Many large portable applications expect such a facility on an
implementation-specific basis. Others would use one if available.
Even if implementations don't use the provided optimizers primitively,
user macros and code-walkers can invoke them, so the facility wouldn't
be completely useless even in those implementations.
The rationale for giving optimizers precedence over INLINE declarations
is that the optimizer can look for special patterns in the arguments,
and defer to the inline if it doesn't find them.
Current Practice:
Symbolics Genera provides an optimizer facility which is more elaborate
but not fundamentally incompatible with this facility.
Many (if not most) serious implementations provide a similar facility.
For example, Lucid provides "compiler macros" which serve the same
purpose.
Cost to Implementors:
Since the implementation is not required to use this facility, the
cost of providing the proposed support is very small.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Portable code would be slower than necessary in some situations.
Benefits:
Some existing non-portable code could become portable.
Aesthetics:
Providing a separate optimizer definition from a main function definition
makes a possibility that the optimizer and main function could drift out
of synch. However, most places where this gets used in the first place
are places where speed is of paramount importance and the programmer is
willing to invest effort in maintaining things correctly and to accept the
risk of lossage if s/he fails.
This is a fairly clean and simple extension which adds significant
power to the compiler.
Discussion:
Pitman strongly supports this proposal, the design of which is modeled
directly after that which has been used in Macsyma for many years.
Information about argument type can come from two different sources:
THE and declarations (via PROCLAIM or DECLARE). The former information
is portably accessible, the latter is not. While a separate proposal
(SYNTACTIC-ENVIRONMENT-ACCESS) for allowing program access to type
declarations would be make this facility more useful, it is still
quite useful without it, as the examples from Macsyma illustrate.
Some implementations provide a way to provide more than one optimizer
for the same function. A multiple optimizer facility can be written
in terms of this simpler facility and vice versa, so the simpler of
the two facilities is proposed here.
Some people have suggested that they would like to see a pattern
matching facility integrated into this facility. The design of a
facility that would satisfy everyone would take a lot of time and
effort. At this point, there is no chance that the design of such a
facility would occur in time for acceptance into the standard.
The choice is this or nothing. Pitman thinks the language is much
better off with some form of optimization support than none.
David Moon says:
I'm not a fan of documentation strings, but shouldn't DEFINE-OPTIMIZER
allow them? Was their omission accidental or intentional?
It was probably accidental, but it's hard to say what should be done
with them if they are supported. Presumably the function already
would have its own FUNCTION documentation. Should the DOCUMENTATION
function be extended to recognize OPTIMIZER as a doc-type symbol?
Loosemore says:
Although I don't really think this is an essential feature to include
in the standard, I don't have any strong objection to adding it. If
people think it's a good idea to provide a standard interface for this
kind of thing, this is a good proposal for doing it -- it's fairly
simple, doesn't introduce any radically new ideas, and is general
enough to allow alternate interfaces (such as the pattern matcher) to
be layered on top of it.
From Barry Margolin:
While I like the proposal in general, I don't think it's appropriate to
add this to the language at this time. If most Lisp vendors are in
favor of it, though, my objection is pretty weak. But there's still the
editorial issue of adding it to the standard. I don't really think it's
worth it for the first version of the standard.
Also, I don't see a whole lot of value in portable optimizers. Yes, the
Macsyma example is a good one, but the real value of optimizers comes
when they translate into calls to extra fast, internal functions.
Portable optimizers can't do this, and non-portable optimizers don't
need to be defined using a portable mechanism.
From Kent Pitman:
I believe this claim is unsubstantiated and unsubstantiable. In many
implementations, internal functions have no special property that user
programs do not. In some cases, that makes the optimizers that much
more important since most internal functions run a constant factor
faster, but do not have any algorithmic leverage over user programs.
Optimizers are potentially able to do much better than built-in
optimizations because they can use domain-specific information that
is beyond the power of even the proverbial SCC (Sufficiently Clever
Compiler).
Optimizers have been around for a -long- time. They are not new
technology. If we cannot adopt at least this much this time, I see
no reason why for CL 2000 we won't have the exact same arguments
raised and we -still- won't get anything. On the other hand, if we
adopt them now we get years of field testing, and next time there
will be a lot of users with suggestions about how to improve them.
Some progress must be made incrementally -- but no progress is made
if the increment is zero.
The risks are very low. This proposal already says the optimizer
function has to be semantics-preserving, and that it might never be
called. It's hard to see how that can go wrong.
For so little cost and so much potential gain, I think it is worth any
associated risk.
From Robert Krajewski:
I think a portable optimizer definer is a fine idea. It's especially
useful for authors of Common Lisp-embedded subsystems that offer safe
access to their data structures in a development environment, but who
also wish to produce fast code for delivery. In such cases, an
optimizer should only run when unsafe code is desired.
From Richard Gabriel:
I oppose this proposal. First, optimization is rarely something that
can be done portably. Using a name like define-optimizer gives the
impression that something will be done more optimally, and maybe it
won't.
Second, it appears that this functionality is isomorphic to macros,
except possibly macros that are only in effect during compilation.
Third, it seems to solve a problem that is addressed by all the various
abstraction mechanisms around already.
Fourth, it is part of a trend I will call ``featherbedding'', which I
will use in my messages to refer to adding comfortable features to
Common Lisp that are redundant or not strictly necessary.
From Dick Waters:
I would like to say that I think that compiler optimizers are an
extremely good idea---right up there with the best of the ideas ever
presented to the committee.
I really hate having to make things macros for trivial reasons,
because this blocks you from funcalling them and using them as
arguments to MAPCAR REDUCE etc. If this mechanism were in Common Lisp
I would use it all the time. I bet it would cover a significant chunk
of what I use macros for.
To be more specific, there are a number of places where such compiler
optimizers would be of HUGE benefit in my portable implementation of
SERIES. In particular, they would be an appropriate framework in
which to state the whole thing. Now, since I have to do it all with
macros, a number of things that should, by every right, be functions
have to be macros instead. This in fact makes it impossible to make an
implementation of what I really want.
-------
∂23-Mar-89 1552 X3J13-mailer Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:51:46 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA03601g; Thu, 23 Mar 89 13:23:09 PST
Received: by challenger id AA24966g; Thu, 23 Mar 89 13:18:25 PST
Date: Thu, 23 Mar 89 13:18:25 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903232118.AA24966@challenger>
To: x3j13@sail.stanford.edu
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Moon raises an important point about conceptual versus
representational types. It always struck me that simple arrays as
defined in Version 9 were somewhat like each of these two things.
Moon also points out the FIXNUM/SIMPLE-ARRAY analogy. Let's look more
at this analogy:
Suppose I have some piece of code like this:
(defun f (x) ...)
and I want to know whether to put in a FIXNUM declaration for a
different target CL about which I know everything. In order to do that
I have to look at the calls to F to see whether they all produce
FIXNUMs for the target CL. Usually I look no further, but in general I
must look all the way back from each call to F to the origin of the
argument that is passed to F. The reason I usually have to look no
further than the call is that this is typically where the number is
created.
Now suppose the piece of code really takes an array, and I want to put
in a SIMPLE-ARRAY declaration so that I can get fast array access. I
cannot look only at the calls to F, nor can I look at the creation of
the arrays that get passed to F, but I have to look at all operations
on F to see whether any of them is an ADJUST-ARRAY. That is, I cannot
simply look all the way back from each invocation of F to the creation
of the argument that is passed, but I also have to look all the way
forward to the termination of the program.
In the FIXNUM example, this is as if I had to look at all the
operations on the numbers being fed to F (either before or *after* F
in execution order) to see whether some particular operation was
applied to an argument to F. That is, I cannot look at dataflow up to
the call to F to determine whether it is an simple array, I have to
look at the entire life history of the objects passed to F.
This leads to what I think is an interesting point. Some theorists
define a type as being the set of objects that can be passed to a
particular set of functions or operations. That is, a number is
something you can add, subtract, multiply, and divide, for example.
Some describe this by saying that a type is the set of objects that
respond to the same protocol.
In all implementations, FIXNUMs and BIGNUMs can be operated on by the
same set of functions and operations. Thus, FIXNUMs and BIGNUMs are
merely representational variants on the same type (namely, INTEGER).
In all implementations, ARRAY can be operated on by AREF, SETF of
AREF, and ADJUST-ARRAY (and some others).
In some implementations, SIMPLE-ARRAY can be operated on by AREF, SETF
of AREF (and some others), but not by ADJUST-ARRAY. Thus, in some
implementations SIMPLE-ARRAY responds to a different protocol and so
it is a conceptual type, while in implementations it is a
representational type.
This is, I think, the source of my uneasiness about the whole issue:
Version 9 legitimizes SIMPLE-ARRAY being a representational type in
some Common Lisps and a conceptual type in others. Only people who are
porting will notice the difference.
-rpg-
∂23-Mar-89 1526 X3J13-mailer issue CONSTANT-COMPILABLE-TYPES, version 9
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:24:39 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA11960; Thu, 23 Mar 89 13:45:42 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12712; Thu, 23 Mar 89 13:45:38 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232045.AA12712@defun.utah.edu>
Date: Thu, 23 Mar 89 13:45:37 MST
Subject: issue CONSTANT-COMPILABLE-TYPES, version 9
To: x3j13@sail.stanford.edu
There have been extensive revisions made to this writeup since the
previous version was distributed last week. Most of the changes,
however, have been of an editorial nature. There are two substantive
changes to watch out for:
- The special treatment for uninterned symbols (requiring EQLness of
symbols within a single file to be preserved) has been removed from
this issue, since that more properly falls into the domain of issue
CONSTANT-CIRCULAR-COMPILATION.
- The problems of what to do with constant functions have been deferred
to a new issue, CONSTANT-FUNCTION-COMPILATION.
Forum: Compiler
Issue: CONSTANT-COMPILABLE-TYPES
References: CLtL pp. 56, 77-80, 324
Issue CONSTANT-MODIFICATION
Issue CONSTANT-CIRCULAR-COMPILATION
Issue CONSTANT-COLLAPSING
Issue QUOTE-SEMANTICS
Issue LOAD-OBJECTS
Issue CONSTANT-FUNCTION-COMPILATION
Category: CLARIFICATION, ADDITION
Edit history: 11/07/88, V1 by Cris Perdue
11/14/88, V2 by Cris Perdue
11/22/88, V3 by Cris Perdue
12/20/88, V4 by Cris Perdue
01/06/89, V5 by Sandra Loosemore (minor editorial
clarifications, expand discussion)
03/05/89, V6 by Cris Perdue (more response to comments,
especially from Moon and and from Loosemore)
03/05/89, V7 by Loosemore (more editorial tweaks)
03/13/89, V8 by Loosemore (discussion)
03/22/89, V9 by Loosemore (restructure)
Status: Ready for release
Problem description:
CLtL does not specify what objects can be in compiled constants and it
does not say what relationship there is to be between the constant
passed to the compiler and the one that is established by compiling
and then loading its file. Relevant remarks in CLtL concerning file
compilation and the definition of QUOTE suggest that the compiler
handles constants in ways that are not actually possible.
Introduction to the proposal:
The proposal CONSTANT-COMPILABLE-TYPES:SPECIFY attempts to spell out
what types can appear in compiled constants, and what it means when
they appear.
The key is a definition of an equivalence relationship between Lisp
objects, "similarity as constants". Code passed through the file
compiler and then loaded must behave as though quoted constants in it
are "similar" to quoted constants in the corresponding source code.
Issue CONSTANT-COLLAPSING addresses the issue of whether, for two
objects that are not EQL in the source code (but which are similar as
constants), the corresponding objects in the compiled code may be
EQL.
Issue CONSTANT-CIRCULAR-COMPILATION addresses the issue of whether,
for two objects that are EQL in the source code, the corresponding
objects in the compiled code must also be EQL.
Comments within the text of the proposal are enclosed in double angle
brackets, <<like this>>.
Proposal: CONSTANT-COMPILABLE-TYPES:SPECIFY
An object may be used as a quoted constant processed by COMPILE-FILE
if the compiler can guarantee that the resulting constant established
by loading the compiled file is "similar as a constant" to the
original.
Some types of objects, such as streams, are not supported in constants
processed by the file compiler. Such objects may not portably appear
as constants in code processed with COMPILE-FILE. Conforming
implementations are required to handle such objects either by having
the compiler and/or loader reconstruct an equivalent copy of the
object in some implementation-specific manner; or by having the
compiler signal an error.
Of the types supported in constants, some are treated as aggregate
objects. For these types, being similar as constants is defined
recursively. We say that an object of these types has certain "basic
attributes", and to be similar as a constant to another object, the
values of the corresponding attributes of the two objects must also be
similar as constants.
This kind of definition has problems with any circular or "infinitely
recursive" object such as a list that is an element of itself. We use
the idea of depth-limited comparison, and say that two objects are
similar as constants if they are similar at all finite levels. This
idea is implicit in the definitions below, and applies in all the
places where attributes of two objects are required to be similar as
constants.
The following terms are used throughout this proposal:
The term "constant" refers to a quoted or self-evaluating constant,
not a named (defconstant) constant.
The term "source code" is used to refer to the objects constructed
when COMPILE-FILE calls READ, and additional objects constructed by
macroexpansion during COMPILE-FILE.
The term "compiled code" is used to refer to objects constructed by
LOAD.
Two objects are defined to be "similar as a constant" if and only if
they are both of one of the types listed below and satisfy the
additional requirements listed for that type.
Number
Two numbers are similar as constants if they are of the same type
and represent the same mathematical value.
Character
Two characters are similar as constants if they both represent
the same character.
<<Note that this definition has to depend on the results of the
Character Set proposals. The intent is that this be compatible with
how EQL is defined on characters.>>
Symbol
Issue COMPILE-FILE-SYMBOL-HANDLING defines how the file compiler
and loader handle interned symbols.
An uninterned symbol in the source code is similar as a constant
to an uninterned symbol in the compiled code if their print names
are similar as constants.
Package
A package in the source code is similar as a constant to a package in
the compiled code if their names are similar as constants. Note that
the loader finds the corresponding package object as if by calling
FIND-PACKAGE with the package name as an argument. An error is
signalled if no package of that name exists at load time.
Random-state
Let us say that two random-states are functionally equivalent if
applying RANDOM to them repeatedly always produces the same
pseudo-random numbers in the same order.
Two random-states are similar as constants if and only if copies of
them made via MAKE-RANDOM-STATE are functionally equivalent.
Note that a constant random-state object cannot be used as the "state"
argument to the function RANDOM (because RANDOM side-effects this
data structure).
Cons
Two conses are similar as constants if the values of their respective
CAR and CDR attributes are similar as constants.
Array
Two arrays are similar as constants if the corresponding values each
of the following attributes are similar as constants:
For 1-dimensional arrays:
LENGTH, ARRAY-ELEMENT-TYPE, and ELT for all valid indices.
For arrays of other dimensions:
ARRAY-DIMENSIONS, ARRAY-ELEMENT-TYPE, AREF for all valid indices.
In addition, if the array in the source code is a SIMPLE-ARRAY, then
the corresponding array in the compiled code must also be a
SIMPLE-ARRAY. If the array in the source code is displaced, has a
fill pointer, or is adjustable, the corresponding array in the
compiled code is permitted to lack any or all of these qualities.
Hash Table
Two hash tables are similar as constants if they meet the following
three requirements:
(1) They both have the same test (e.g., they are both EQL hash tables).
(2) There is a unique one-to-one correspondence between the keys of
the two tables, such that the corresponding keys are similar as
constants.
(3) For all keys, the values associated with two corresponding keys
are similar as constants.
If there is more than one possible one-to-one correspondence between
the keys of the two tables, the results are unspecified. A conforming
program cannot use such a table as a constant.
Pathname
Two pathnames are similar as constants if all corresponding pathname
components are similar as constants.
Stream, Readtable, Generic-function, Method
Objects of these types are not supported in compiled constants.
Function
Issue CONSTANT-FUNCTION-COMPILATION specifies how the compiler and
loader handle constant functions.
Structure, Standard-object
<<There is a cl-cleanup issue, LOAD-OBJECTS, pending which proposes
a mechanism for dealing with objects.>>
Rationale:
For the benefit of users, this proposal tries to define a fairly large
set of types that all Common Lisp implementations are to handle. It
also attempts to leave room for implementations to differ. Some
implementations have made opposing choices because the language
doesn't specify one over the other. Some implementations already
handle constants that this proposal defines as not valid in Common
Lisp programs, and that is useful to users of those systems.
Different implementors have different amounts of resources to apply to
their system, and implementations differ in their whole approach in
some cases.
This proposal appears to reflect user demand and appears not to exceed
the capabilities of most implementations of the language.
Current practice:
>From Gail Zacharias (Nov 14): "Coral pretty much implements this
proposal (I think we currently coalesce hash table keys, but that's
just a bug that will be fixed). We also fasdump packages (using the
package name) and compiled functions (but not foreign functions). For
symbols, we dump the name, and if (roughly speaking) the symbol would
get printed with a package prefix, we also dump the package name and
load the symbol into that package (otherwise it gets loaded into the
current load-time package)."
>From David Gray (Nov 9): "The Explorer can compile constant functions,
read tables, and hash tables; an error is signalled for a stream. A
package object used to break the compiler but in release 5 it has been
fixed to generate instructions to call FIND-PACKAGE on the package
name at load time." (Nov 15): [The Explorer does not guarantee
retention of displaced-to and displaced-index-offset attributes.]
"The Explorer also does not currently support dumping closures (either
compiled or evaluated), although non-closure compiled functions can be
dumped."
>From David Moon (Jan 24): "Symbolics Genera current practice: aside
from some current bugs we have with circular structures of certain
types and with preserving the identity of CONSes under EQ, this is
more or less consistent with our current practice, if you made the
changes implied by my earlier comments. We preserve the :displaced-to
and :fill-pointer array attributes. I doubt that we do what the
proposal says for hash-tables, readtables, and random-states. We
support dumping compiled and interpreted functions, but not closures,
which in effect means we don't support dumping functions."
>From Sandra Loosemore (Mar 3): "UCL currently can handle only
constants that are of type number, character, symbol, cons,
simple-vector, or string (which it turns into simple-string). It
signals an error if an attempt is made to compile any other kind of
object as a constant."
Adoption cost:
Not known. Probably moderate or low -- for most implementations. The
cost would be to implementors rather than users since this part of the
language is currently underspecified. The author believes the cost
will be reasonable for KCL, an implementation where there is some
concern about this issue.
This proposal is close to compatible with the Franz, Lucid, Coral,
Texas Instruments, and Symbolics implementations. It is probably
compatible or nearly compatible with other "Lisp Machine"
implementations.
Benefits:
Users would be able to use aggregate objects in constants with
confidence about the behavior of their code.
Conversion cost:
Where this proposal *requires* different behavior than an existing
implementation, there is a conversion cost for users of that
implementation. It appears that this cost will be small, less than
the cost of leaving things unspecified.
Esthetics:
Since there is no adequate definition at present, a fuller definition
would be more esthetic.
Discussion:
This proposal does leave some user-visible attributes of objects
unspecified across the compile-and-load process, except that they must
be consistent with the attributes that must be retained. This
situation is a compromise between the desire for full specification on
the one hand, and on the other hand the desire to leave freedom for
different implementations to remain different and to support some
optimizations such as compacting hash tables and "simplifying" arrays.
Proposals will be entertained for tighter specification of datatypes
such as arrays.
The definition of similarity for random-states supports the
possibility of random states that are immutable because of being in
compiled constants.
Readtables need not be supported by an implementation. If a readtable
contains only symbols to represent functions, here is Cris Perdue's
suggested spec for similarity of readtables:
Character syntax type for each character in the table;
function for each readmacro character, mappings for
dispatch macros; whether terminating or nonterminating
for each readmacro.
Interest has been expressed by a number of people including users, in
support for user-definable "dumping" of CLOS objects and structure
instances. The cleanup issue LOAD-OBJECTS deals with this.
This subsumes the issue CONSTANT-ARRAY-ATTRIBUTES.
Earlier versions of this proposal specified an additional constraint
on uninterned symbols, requiring EQLness to be preserved across the
entire file. However, this special case was removed because it was
thought that including it in this issue made its presentation
unnecessarily complicated, since preservation of EQLness is really a
separate issue (CONSTANT-CIRCULAR-COMPILATION). A consequence of the
decision to remove the special casing for uninterned symbols is that,
unless we accept one of the two CONSTANT-CIRCULAR-COMPILATION
proposals that requires EQLness of constants to be preserved, the
behavior for uninterned symbols will be rather strange. PCL will
reportedly break if uninterned symbols that are EQL in the source code
do not remain EQL in the compiled code.
-------
∂23-Mar-89 1526 X3J13-mailer issue SYNTACTIC-ENVIRONMENT-ACCESS, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:25:09 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA17795; Thu, 23 Mar 89 16:24:48 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12801; Thu, 23 Mar 89 16:24:44 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232324.AA12801@defun.utah.edu>
Date: Thu, 23 Mar 89 16:24:42 MST
Subject: issue SYNTACTIC-ENVIRONMENT-ACCESS, version 6
To: x3j13@sail.stanford.edu
There have been a number of changes to the writeup on this issue since
version 4, which was distributed last week. (Version 5 was circulated
only to cl-compiler.) There are some new functions proposed, and
others have been combined. There seemed to be general agreement that
only the material in proposal SMALL was anywhere near ready to be
standardized at this time, so proposals MEDIUM and LARGE have gone
away.
We have still been having problems deciding upon the exact form of
accessors for declarations. If what's specified in this version is
not acceptable, we may have to scrap that part of the proposal for
now.
Forum: Compiler
Issue: SYNTACTIC-ENVIRONMENT-ACCESS
References: CLtL Chapter 8: Macros,
Issue MACRO-FUNCTION-ENVIRONMENT
Issue GET-SETF-METHOD-ENVIRONMENT
Issue COMPILE-FILE-ENVIRONMENT
Issue FUNCTION-NAME
Issue PROCLAIM-LEXICAL
Issue MACRO-ENVIRONMENT-EXTENT
Issue DESTRUCTURING-BIND
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: ADDITION
Edit history: Version 1, 2-Oct-88, Eric Benson
Version 2, 17-Feb-89, Kim A. Barrett
Version 3, 9-Mar-89, Kim A. Barrett (respond to comments)
Version 4, 12-Mar-89, Sandra Loosemore (more revisions)
Version 5, 20-Mar-89, Sandra Loosemore (only proposal SMALL)
Version 6, 23-Mar-89, Sandra Loosemore (more revisions)
Status: **DRAFT**
Problem description:
When macro forms are expanded, the expansion function is called with
two arguments: the form to be expanded, and the environment in which
the form was found. The environment argument is of limited utility.
The only use sanctioned currently is as an argument to MACROEXPAND or
MACROEXPAND-1 or passed directly as an argument to another macro
expansion function. Recent cleanup issues propose to allow it as an
argument to MACRO-FUNCTION and to GET-SETF-METHOD.
It is very difficult to write a code walker that can correctly handle
local macro and function definitions, due to insufficient access to
the information contained in environments and the inability to
augment environments with local definitions.
Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:SMALL):
The following functions provide information about syntactic
environment objects. In all of these functions the argument named ENV
is an environment of the sort received by the &ENVIRONMENT argument to
a macro or as the environment argument for EVALHOOK. (It is not
required that implementations provide a distinguished representation
for such objects.) Optional "env" arguments default to NIL, which
represents the local null lexical environment (containing only global
definitions and proclamations that are present in the runtime
environment). All of these functions should signal an error of type
TYPE-ERROR if the value of an environment argument is not a syntactic
environment.
The accessors VARIABLE-INFORMATION, FUNCTION-INFORMATION, and
DECLARATION-INFORMATION retrieve information about declarations that
are in effect in the environment. Since implementations are
permitted to ignore declarations (except for SPECIAL declarations),
these accessors are required only to return information about
declarations that were explicitly added to the environment using
AUGMENT-ENVIRONMENT. Implementations are also permitted to
canonicalize declarations, so the information returned by the
accessors may not be identical to the information that was passed to
AUGMENT-ENVIRONMENT.
VARIABLE-INFORMATION variable &optional env [Function]
This function returns information about the interpretation of the
symbol VARIABLE when it appears as a variable within the lexical
environment ENV. The following four values are returned.
The first value indicates the type of definition or binding which is
apparent in ENV:
NIL There is no apparent definition or binding for variable.
:SPECIAL VARIABLE refers to a special variable, either declared
or proclaimed.
:LEXICAL VARIABLE refers to a lexical variable.
:SYMBOL-MACRO VARIABLE refers to a SYMBOL-MACROLET binding.
:CONSTANT VARIABLE refers to a named constant, defined by
DEFCONSTANT.
[Note: If issue PROCLAIM-LEXICAL passes, then the :LEXICAL result
will also refer to variables proclaimed lexical.]
The second value indicates whether there is a local binding of the
name. If the name is locally bound, the second value is true.
Otherwise, NIL is returned.
The third value is the type specifier associated with the variable
named by the symbol in the environment. If no explicit association
exists, either by PROCLAIM or DECLARE, then the result is the type
specifier T. It is permissible for implementations to return a type
specifier that is equivalent to or a supertype of the one appearing
in the original declaration.
The fourth value is a property list of containing information about
declarations that apply to the apparent binding of the variable.
The keys in the property list are symbols which name
declaration-specifiers, and the format of the corresponding values
depends on the particular declaration-specifier involved. The only
standard declaration-specifier that may appear as a key in this
property list is IGNORE, with a non-NIL value to indicate that the
variable has been declared IGNORE. If an implementation supports
additional declaration-specifiers that apply to variable bindings,
those declaration-specifiers may also appear in the property list.
Programmers are reminded that the global binding type may differ from
the local one, and can be retrieved by calling VARIABLE-INFORMATION
again with a null lexical environment.
FUNCTION-INFORMATION function &optional env [Function]
This function returns information about the interpretation of the
function name FUNCTION when it in a functional position within
lexical environment ENV. The following four values are returned.
The first value indicates the type of definition or binding of
the function name which is apparent in ENV:
NIL There is no apparent definition for FUNCTION.
:FUNCTION FUNCTION refers to a function.
:MACRO FUNCTION refers to a macro.
:SPECIAL-FORM FUNCTION refers to a special form.
Some function names may refer to both a global macro and a global
special form. In such a case, the macro takes precedence, and
:MACRO is returned as the first value.
The second value specifies whether the definition is local or
global. If local, the second value is true, and it is false when
the definition is global.
The third value is the type specifier associated with the function
in the environment, or the symbol FUNCTION if there is no functional
type declaration or proclamation associated with the function. This
value might not include all the apparent FTYPE declarations for
FUNCTION. It is permissible for implementations to return a type
specifier that is equivalent to or a supertype of the one that
appeared in the original declaration.
The fourth value is a property containing informatin about
declarations that apply to the apparent binding of the function.
The keys in the property list are symbols which name
declaration-specifiers, and the format of the corresponding values
depends on the particular declaration-specifier involved. The only
standard declaration-specifiers that may appear as a key in this
property list are INLINE and NOTINLINE, with a non-NIL value to
indicate that the function has been declared INLINE or NOTINLINE
(respectively). If an implementation supports additional
declaration-specifiers that apply to function bindings, those
declaration-specifiers may also appear in the property list.
[Note: The use of "function name" rather than "symbol" as the
description of the function argument is intended to be compatible
with the various proposals to extend the syntax of function
specifiers. If no such change actually occurs then this would only
refer to symbols.]
AUGMENT-ENVIRONMENT env &KEY variable
symbol-macro
function
macro
declare [Function]
This function returns a new environment containing the information
present in ENV, augmented with the information provided by the keyword
arguments. It is intended to be used by program analyzers that perform
a code walk.
The arguments are supplied as follows:
:VARIABLE A list of symbols which shall be visible as bound
variables in the new environment. Whether each
binding is to be interpreted as special or lexical
depends on SPECIAL declarations recorded in the
environment or provided in the :DECLARE argument list.
:SYMBOL-MACRO A list of symbol macro definitions, specified as a
list of (name definition) lists (that is, in the same
format as the CADR of a SYMBOL-MACROLET special form).
The new environment will have local symbol-macro bindings
of each symbol to the corresponding expansion, so that
MACROEXPAND will be able to expand them properly.
:FUNCTION A list of function names which shall be visible as local
function bindings in the new environment.
:MACRO A list of local macro definitions, specified as a
list of (name definition) lists. Each definition must
be a function of two arguments (a form and an environment).
The new environment will have local macro bindings of each
name to the corresponding expander function, which
will be returned by MACRO-FUNCTION and used by
MACROEXPAND.
:DECLARE A list of decl-specs. Information about these
declarations can be retrieved from the resulting
environment using the VARIABLE-INFORMATION,
FUNCTION-INFORMATION, and DECLARATION-INFORMATION
accessors.
An error is signalled if any of the symbols naming macros in the
:SYMBOL-MACRO alist are also included in the :VARIABLE list.
An error is signalled if any of the names specified as keys in the
:MACRO alist are also included in the :FUNCTION list. The consequences
of destructively modifying the list structure of any of the arguments
to this function are undefined.
The extent of the returned environment is the same as the extent of
the argument environment. The result may share structure with the
argument environment, but the argument environment is not modified.
While an environment argument from EVALHOOK is permitted to be used
as the environment argument for this function, the reverse is not
true. If an attempt is made to use the result of AUGMENT-ENVIRONMENT
as the environment argument for EVALHOOK, the consequences are
undefined. The environment returned by AUGMENT-ENVIRONMENT may only
be used for syntactic analysis, ie. the functions specified by this
proposal and functions such as MACROEXPAND.
PARSE-MACRO name lambda-list body &optional env [Function]
This function is used to process a macro definition in the same way
as DEFMACRO and MACROLET. It returns a lambda-expression that accepts
two arguments (a form and an environment). The "name", "lambda-list",
and "body" arguments correspond to the parts of a DEFMACRO or MACROLET
definition.
The "lambda-list" argument may include &ENVIRONMENT and &WHOLE.
The "name" argument is used to enclose the "body" in an implicit
BLOCK, and may also be used for implementation-dependent purposes
(such as including the name of the macro in error messages if the
form does not match the lambda-list).
ENCLOSE lambda-expression &optional env [Function]
This function returns an object of type FUNCTION that is equivalent
to what would be obtained by evaluating `(FUNCTION ,LAMBDA-EXPRESSION)
in syntactic environment ENV. The consequences are undefined if any
of the local variable or function bindings that are visible in the
lexical environment represented by ENV are referenced within the
LAMBDA-EXPRESSION.
DECLARATION-INFORMATION decl-spec &optional env [Function]
This function returns a list of declaration-specifiers whose CAR
is the symbol DECL-SPEC that are in force in the environment ENV,
sorted so that the most recent declaration is first on the list.
Only declarations that do not apply to function or variable
bindings (i.e., those that are "pervasive") can be accessed with
this function.
It is required that this function recognize OPTIMIZE and DECLARATION
as DECL-SPECs. If an implementation has been extended to recognize
additional pervasive declaration specifiers in DECLARE or PROCLAIM,
it is required that either the DECLARATION-INFORMATION function
should also recognize those declarations, or that the implementation
provide an accessor that is specialized for that declaration
specifier.
Rationale:
This proposal defines a minimal set of accessors (VARIABLE-INFORMATION,
FUNCTION-INFORMATION, and DECLARATION-INFORMATION) and a constructor
(AUGMENT-ENVIRONMENT) for environments.
The PARSE-MACRO function is provided so that users don't have to
write their own code to destructure macro arguments. Most
implementations probably already have a similar internal function.
The ENCLOSE function is necessary to support early evaluation of
defining macros such as DEFMACRO by a program analyzer. It is
also necessary to support the revised MACROLET semantics proposed in
issue DEFINING-MACROS-NON-TOP-LEVEL; all implementations would be
required to have similar functionality internally.
Making declarations from an &ENVIRONMENT or EVALHOOK environment
optional continues to allow implementations the freedom to simply
ignore all such declarations in the compiler or interpreter.
Examples:
#1: This example illustrates the first value returned by the function
VARIABLE-INFORMATION.
(DEFMACRO KIND-OF-VARIABLE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-INFORMATION VAR ENV))
(DEFVAR A)
(DEFUN TEST ()
(LET (B)
(LET (C)
(DECLARE (SPECIAL C))
(SYMBOL-MACROLET ((D ANYTHING))
(LIST (KIND-OF-VARIABLE A)
(KIND-OF-VARIABLE B)
(KIND-OF-VARIABLE C)
(KIND-OF-VARIABLE D)
(KIND-OF-VARIABLE E))))))
(TEST) -> (:SPECIAL :LEXICAL :SPECIAL :SYMBOL-MACRO NIL)
#2: This example illustrates the first value returned by the function
FUNCTION-INFORMATION.
(DEFMACRO KIND-OF-FUNCTION (FUNCTION-NAME &ENVIRONMENT ENV)
`',(FUNCTION-INFORMATION FUNCTION-NAME ENV))
(DEFUN A ())
(DEFMACRO B ())
(DEFUN TEST ()
(FLET ((C ()))
(MACROLET ((D ()))
(MULTIPLE-VALUE-CALL #'LIST
(KIND-OF-FUNCTION A)
(KIND-OF-FUNCTION B)
(KIND-OF-FUNCTION QUOTE)
(KIND-OF-FUNCTION C)
(KIND-OF-FUNCTION D)
(KIND-OF-FUNCTION E)))))
(TEST) -> (:FUNCTION NIL
:MACRO NIL
:SPECIAL-FORM NIL
:FUNCTION T
:MACRO T
NIL NIL)
#3: This example shows how a code-walker might walk a MACROLET special
form. It assumes that the revised MACROLET semantics described in
proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW are in effect.
(defun walk-macrolet (form env)
(let ((macros (make-macro-definitions (cadr form) env)))
(multiple-value-bind (body decls) (parse-body (cddr form))
(walk-implicit-progn
body
(augment-environment env :macro macros :declare decls))
)))
(defun make-macro-definitions (defs env)
(let ((results nil))
(dolist (d defs)
(push (list (car d)
(enclose (parse-macro (car d) (cadr d) (cddr d) env)
env))
results))
results))
Cost to Implementors:
Most implementations already record some of this information in some
form. Providing these functions should not be too difficult, but it
is a more than trivial amount of work.
Cost to Users:
This change is upward compatible with user code.
Current practice:
No implementation provides all of this interface currently. Portable
Common Loops defines a subset of this functionality for its code
walker and implements it on a number of diffent versions of Common
Lisp.
Discussion:
The first version of this proposal expressly did not deal with the
objects which are used as environments by EVALHOOK. This version is
extended to support them in the belief that such environments share a
lot of functionality with the syntactic environments needed by a
compiler. While the two types of environments might have very
different implementations, there are many operations which are
reasonable to perform on either type, including all of the accessor
functions described by this proposal.
AUGMENT-ENVIRONMENT currently requires signaling an error when
symbol-macro names match variable names in the same call. This could
be reduced to "should signal". By requiring the error signaling, this
proposal is compatable with Proposal SYMBOL-MACROLET-DECLARE:ALLOW,
which says
"... signals an error if a SPECIAL declaration names one of the symbols
being defined as a symbol-macrolet."
Maintaining compatability with the SYMBOL-MACROLET-DECLARE proposal
allows fairly trivial implementations of the SYMBOL-MACROLET
special-form in terms of the AUGMENT-ENVIRONMENT function.
Moon notes:
Symbolics Genera includes an undocumented internal macro, used
quite a bit in the implementation of the interpreter and code
analyzers, that could have been called WITH-AUGMENTED-ENVIRONMENT,
taking keywords like AUGMENT-ENVIRONMENT and also body forms,
and producing an environment with dynamic extent bound to a
variable within the body forms. Would it be useful to have this
too, or instead of AUGMENT-ENVIRONMENT? I'm unsure.
Some people have indicated they think that the :MACRO argument (and
the :SYMBOL-MACRO argument too?) to AUGMENT-ENVIRONMENT should be an
a-list of the form (name . definition).
Some people have indicated they think that implementations must never
discard any declarations, even if they are not otherwise used by the
interpreter or compiler. Proposal SMALL is consistent with what CLtL
says (implementations are free to ignore all declarations except
SPECIAL declarations), but the DECLARATION-INFORMATION function may
not be particularly useful unless it is guaranteed to do something.
Requiring implementations to keep track of declarations they'd otherwise
ignore would involve some implementation cost and also may incur a
performance penalty.
-------
∂23-Mar-89 1527 X3J13-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:25:15 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA14465; Thu, 23 Mar 89 14:45:11 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12759; Thu, 23 Mar 89 14:45:06 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232145.AA12759@defun.utah.edu>
Date: Thu, 23 Mar 89 14:45:03 MST
Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 7
To: x3j13@sail.stanford.edu
A paragraph on order of processing of top-level forms (which used to be
discussed in issue DEFINING-MACROS-NON-TOP-LEVEL) has been added to
this version of the writeup.
Issue: EVAL-WHEN-NON-TOP-LEVEL
Forum: Compiler
References: EVAL-WHEN (CLtL pp69-70),
Issue DEFINING-MACROS-NON-TOP-LEVEL
Issue COMPILED-FUNCTION-REQUIREMENTS
Issue IN-PACKAGE-FUNCTIONALITY
Issue LOCALLY-TOP-LEVEL
Category: CLARIFICATION/CHANGE
Edit History: 06-May-88, Version 1 by Sandra Loosemore
16-Dec-88, Version 2 by Loosemore (alternate direction)
30-Dec-88, Version 3 by Loosemore (minor wording changes)
07-Jan-89, Version 4 by Loosemore (update discussion)
09-Feb-89, Version 5 by Pitman and Moon (some major changes)
09-Mar-89, Version 6 by Loosemore (clean up wording)
22-Mar-89, Version 7 by Loosemore (order of processing)
Status: Ready for release
Problem Description:
The current description of how the compiler should handle EVAL-WHEN
only makes sense when it appears as a top-level form in the file being
compiled. Is it legitimate for EVAL-WHEN to appear in non-top-level
locations? Even if it is legitimate, what does it mean?
Another issue, referred to here as ``the EVAL-WHEN shadowing problem,''
is that some people have complained that shadowing the symbols EVAL,
COMPILE, or LOAD means that you have to also either shadow EVAL-WHEN
and define it to recognize the new symbol, or else you must resign
yourself to writing (EVAL-WHEN (... LISP:EVAL ...) ...),etc. all over.
While the goal here is not to solve this problem, it might be possible
to solve both problems at once.
There are two proposals presented here, GENERALIZE-EVAL and
GENERALIZE-EVAL-NEW-KEYWORDS.
Background/Analysis:
The proposal which follows was constructed with the following goals
in mind:
1. The lexical and dynamic environment for the EVAL-WHEN body should
be the same for each situation. That is, the body should ``mean
the same thing'' regardless of which situation is being processed.
2. The evaluation context for EVAL-WHEN should be the current
lexical environment.
3. At execution time, EVAL-WHEN should always return the result of
its last form if execution of the body occurred, or NIL if the
body was not executed.
4. If a top-level EVAL-WHEN has a LOAD keyword, its body should
inherit top-level-ness during normal processing. This permits the
use of (EVAL-WHEN (EVAL COMPILE LOAD) ...) at top-level to mean
simply "Do whatever would normally be done for this body, but
also do something at compile time." This, in turn, will later be
the key to allowing defining forms to be usefully described in
terms of EVAL-WHEN.
5. Non-top-level expressions should have no effect until they are
executed. This is the key to making sure that any necessary
environment is present. Since the COMPILE keyword forces effects
to occur earlier than execution time, it follows from this that
any correct solution must not allow the COMPILE keyword to have
an effect at other than top-level.
To accomplish these goals, we formulated the following model:
The purpose of EVAL-WHEN is to accomodate the fact that some of the
semantic processing of an expression may usefully be partitioned
between compile time and run time in some circumstances.
(EVAL-WHEN (EVAL) <code>)
describes a general technique for accomplishing some particular goal
at normal program execution time. However, the pair of expressions
(EVAL-WHEN (COMPILE) <code-A>)
(EVAL-WHEN (LOAD) <code-B>)
can be used to describe an alternate technique for implementing part
of the effect (A) at compile-time, and part of the effect (B) at
load-time.
Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL):
Replace the description of EVAL-WHEN with the following:
EVAL-WHEN ({situation}*) {form}* [Special Form]
The body of an EVAL-WHEN form is processed as an implicit PROGN, but
only in the situations listed. Each SITUATION must be a symbol,
either COMPILE, LOAD, or EVAL.
The use of COMPILE and LOAD controls whether and when processing
occurs for top-level forms. The use of EVAL controls whether
processing occurs for non-top-level forms.
The EVAL-WHEN construct may be more precisely understood in terms of
a model of how the file compiler, COMPILE-FILE, processes forms in a
file to be compiled.
Successive forms are read from the file by the file compiler using
READ. These top-level forms are normally processed in what we call
`not-compile-time' mode. There is one other mode, called
`compile-time-too' mode, which can come into play for top-level
forms. The EVAL-WHEN special form is used to annotate a program
in a way that allows the program doing the processing to select
the appropriate mode.
Processing of top-level forms in the file compiler works as follows:
* If the form is a macro call, it is expanded and the result is
processed as a top-level form in the same processing mode
(compile-time-too or not-compile-time).
* If the form is a PROGN form, each of its body forms is
sequentially processed as top-level forms in the same processing
mode.
* If the form is a COMPILER-LET, MACROLET, or SYMBOL-MACROLET,
the file compiler makes the appropriate bindings and recursively
processes the body forms as an implicit top-level PROGN with those
bindings in effect, in the same processing mode.
* If the form is an EVAL-WHEN form, it is handled according to
the following table:
COMPILE LOAD EVAL compile-time-too Action
Yes Yes -- -- Process body in compile-time-too mode
No Yes Yes Yes Process body in compile-time-too mode
No Yes Yes No Process body in not-compile-time mode
No Yes No -- Process body in not-compile-time mode
Yes No -- -- Evaluate body
No No Yes Yes Evaluate body
No No Yes No do nothing
No No No -- do nothing
"Process body" means to process the body as an implicit top-level
PROGN. "Evaluate body" means to evaluate the body forms as in
implicit PROGN in the dynamic execution context of the compiler and
in the lexical environment in which the EVAL-WHEN appears.
* Otherwise, the form is a top-level form that is not one of the
special cases. If in compile-time-too mode, the compiler first
evaluates the form and then performs normal compiler processing
on it. If in not-compile-time mode, only normal compiler
processing is performed. [The nature of this processing is
defined more precisely in issue COMPILED-FUNCTION-REQUIREMENTS.]
Any subforms are treated as non-top-level forms.
Note that top-level forms are guaranteed to be processed in the order
in which they textually appear in the file, and that each top-level
form read by the compiler is processed before the next is read.
However, the order of processing (including, in particular, macro
expansion) of subforms that are not top-level forms is unspecified.
For an EVAL-WHEN form that is not a top-level form in the file compiler
(that is, one of: in the interpreter; in COMPILE; or in the file
compiler but not at top-level), if the EVAL situation is specified,
its body is treated as an implicit PROGN. Otherwise, the EVAL-WHEN
form returns NIL.
Clarifications/Consequences:
The following effects are logical consequences of the above proposal:
* It is never the case that the execution of a single EVAL-WHEN
expression will execute the body code more than once.
* The keyword `EVAL' is a misnomer because execution of
the body need not be done by EVAL. In compiled code, such as
(DEFUN FOO () (EVAL-WHEN (EVAL) (PRINT 'FOO)))
the call to PRINT should be compiled.
* Macros intended for use in top-level forms should arrange for all
side-effects to be done by the forms in the macro expansion.
The macro-expander itself should not do the side-effects.
Wrong: (defmacro foo ()
(really-foo)
`(really-foo))
Right: (defmacro foo ()
`(eval-when (compile eval load) (really-foo)))
Adherence to this convention will mean that such macros will behave
intuitively when placed in non-top-level positions.
* Placing a variable binding around an EVAL-WHEN reliably captures the
binding because the `compile-time-too' mode cannot occur (because
introducing a variable binding would mean we were not at top level).
For example,
(LET ((X 3))
(EVAL-WHEN (EVAL LOAD COMPILE) (PRINT X)))
will print 3 at execution [load] time, and will not print anything at
compile time. This is important so that expansions of DEFUN and
DEFMACRO can be done in terms of EVAL-WHEN and can correctly capture
the lexical environment.
(DEFUN BAR (X) (DEFUN FOO () (+ X 3)))
might expand into
(DEFUN BAR (X)
(PROGN (EVAL-WHEN (COMPILE)
(COMPILER::NOTICE-FUNCTION-DEFINITION 'FOO '(X)))
(EVAL-WHEN (EVAL LOAD)
(SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))))
which would be treated the same as
(DEFUN BAR (X)
(SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))
by the above rules.
Test Cases:
;; #1: The EVAL-WHEN in this case is not at top-level, so only the EVAL
;; keyword is considered. At compile time, this has no effect.
;; At load time (if the LET is at top level), or at execution time
;; (if the LET is embedded in some other form which does not execute
;; until later) this sets (SYMBOL-FUNCTION 'FOO1) to a function which
;; returns 1.
(LET ((X 1))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO1) #'(LAMBDA () X))))
;; #2: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting
;; (SYMBOL-FUNCTION 'FOO2) to a function which returns 2.
(EVAL-WHEN (EVAL LOAD COMPILE)
(LET ((X 2))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO2) #'(LAMBDA () X)))))
;; #3: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting the
;; function cell of FOO3 to a function which returns 3.
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO3) #'(LAMBDA () 3)))
;; #4: This always does nothing. It simply returns NIL.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (COMPILE)
(PRINT 'FOO4)))
;; #5: If this form occurs at top-level of a file to be compiled, FOO5 is
;; printed at compile time. If this form occurs in a non-top-level
;; position, nothing is printed at compile time. Regardless of context,
;; nothing is ever printed at load time or execution time.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (EVAL)
(PRINT 'FOO5)))
;; #6: If this form occurs at top-level of a file to be compiled, FOO6 is
;; printed at compile time. If this form occurs in a non-top-level
;; position, nothing is printed at compile time. Regardless of context,
;; nothing is ever printed at load time or execution time.
(EVAL-WHEN (EVAL LOAD)
(EVAL-WHEN (COMPILE)
(PRINT 'FOO6)))
Rationale:
This is compatible with any guarantees made by CLtL, and extends the
behavior usefully to non-top-level situations.
This gives a useful meaning to EVAL-WHEN that supports useful and
predictable behavior if defining macros are used in a non-top-level
situation.
The constraints on the order in which top-level forms are processed
ensure that the compile-time effects of defining macros and EVAL-WHENs
at the beginning of the file are visible during the processing of
forms that appear later in the file, which is what most users expect.
Leaving the order of processing of non-top-level forms unspecified
allows the compiler to perform certain kinds of transformations that
change the textual order of subforms. Users should not depend on
side-effects from macros that require them to be expanded in any
particular order.
Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS):
As in GENERALIZE-EVAL, but rename the EVAL keyword to :EXECUTE,
the COMPILE keyword to :COMPILE-TOPLEVEL, and LOAD keyword to
:LOAD-TOPLEVEL.
Deprecate the use of keywords EVAL, COMPILE, and LOAD to EVAL-WHEN.
For compatibility, they are supported in EVAL-WHEN
at top-level, but their meaning is not defined elsewhere.
Rationale:
The fact that the situation keywords chosen are not the same as
those now used means that the change can be added in a way that
is truly upward compatible (not only with CLtL but with existing
practice in implementations which have chosen to extend or `clarify'
the definition given in CLtL) since the meaning of EVAL, COMPILE,
and LOAD in non-top-level situations (which was never spelled
out in CLtL) can legitimately differ from the meaning of these
new keywords.
Using other names and/or the keyword package for the names of
situations solves the EVAL-WHEN shadowing problem.
The name `execute' does not promote the confusion that the body of an
EVAL-WHEN must be executed only in the evaluator. It also does not
promote the confusion that the body of an EVAL-WHEN, regardless of when
executed, must run interpreted.
The names `compile-toplevel' and `load-toplevel' emphasize the fact
that these cases are not interesting in non-top-level positions.
Current Practice:
In Symbolics Genera, the interpreter permits EVAL-WHEN in non-top-level
positions in a way that is compatible with this proposal but both the
COMPILE and COMPILE-FILE functions complain about EVAL-WHEN in a
non-top-level position.
Both Lucid Common Lisp and Kyoto Common Lisp already interpret the
EVAL keyword to mean "execute" in non-top-level situations. Both of
these implementations also make (EVAL-WHEN (LOAD) ...) suppress
compile-time "magic" from defining macros such as DEFMACRO.
IIM describes its EVAL-WHEN as:
(defmacro eval-when (situations &body body &environment env)
(if (not (compiler-environment-p env))
(when (member 'eval situations) `(progn ,@body))
(progn
(when (member 'compile situations)
(if (compiler-at-top-level-p env)
(mapc #'eval body)
(warn "Top-level form encountered at non-top-level.")))
(when (member 'load situations) `(progn ,@body)))))
Note that the interpretation of the EVAL situation and the nesting
behavior is different.
Cost to Implementors:
The actual change to EVAL-WHEN in both cases is probably fairly
localized and straightforward to make in most or all implementations.
The second-order costs of proposal GENERALIZE-EVAL will vary depending
on whether existing implementations have extended the definition of
EVAL-WHEN in incompatible ways. If an implementation has made such
extensions, there may be user and system code which depends on them
and the cost of converting that code may be non-trivial. There is
presumably also documentation impact.
Proposal GENERALIZE-EVAL-NEW-KEYWORDS avoids most or all of the
second-order costs of proposal GENERALIZE-EVAL.
The compiler processing for top-level forms might be implemented
something like:
;;; Forms read by the file compiler are passed to PROCESS-TOP-LEVEL-FORM
;;; with a env compile-time-too both NIL.
(defun process-top-level-form (form env compile-time-too)
(setq form (macroexpand form env))
(cond ((not (consp form))
nil)
((eq (car form) 'progn)
(dolist (f (cdr form))
(process-top-level-form f env compile-time-too)))
((eq (car form) 'compiler-let)
(process-compiler-let form env compile-time-too))
((eq (car form) 'macrolet)
(process-macrolet form env compile-time-too))
((eq (car form) 'symbol-macrolet)
(process-symbol-macrolet form env compile-time-too))
((eq (car form) 'eval-when)
(process-eval-when form env compile-time-too))
(t
(if compile-time-too
(internal-eval form env))
(compile-form form env))
))
(defun process-eval-when (form env compile-time-too)
(let* ((situations (cadr form))
(body (cddr form))
(compile-p (member 'compile situations))
(load-p (member 'load situations))
(eval-p (member 'eval situations)))
(cond ((or (and compile-p load-p)
(and eval-p load-p compile-time-too))
(process-top-level-form `(progn ,@body) env t))
(load-p
(process-top-level-form `(progn ,@body) env nil))
((or compile-p
(and eval-p compile-time-too))
(dolist (f body)
(internal-eval f env)))
(t
nil))))
;;; PROCESS-COMPILER-LET, PROCESS-MACROLET, and PROCESS-SYMBOL-MACROLET
;;; do the obvious things.
;;; INTERNAL-EVAL evaluates "form" in lexical environment "env".
Cost to Users:
Technically, none. Either proposal is technically upward compatible
with CLtL.
Proposal GENERALIZE-EVAL might force some extended implementations to
change incompatibly. As such, some users who depend on
implementation-dependent extensions might have to adjust their code
somewhat to deal with those changes.
Proposal GENERALIZE-EVAL-NEW-KEYWORDS does not force implementations
to change incompatibly, so has no forced impact on users.
Cost of Non-Adoption:
EVAL-WHEN is a mess. Using it as the low-level substrate into which
defining macros should expand, and guaranteeing any predictable effects
of those macros in non-top-level situations is currently difficult and
would continue to be so in the absence of some resolution on this issue.
Benefits:
The costs of non-adoption would be avoided: it would be possible to
use EVAL-WHEN in many situations where it cannot currently be used
reliably.
The portability of many existing tools which use EVAL-WHEN internally
in macros will be enhanced.
Aesthetics:
This generalization of the meaning makes the purpose and uses of
EVAL-WHEN less mysterious. In that sense, aesthetics are simplified
somewhat.
Discussion:
The cleanup issue LOCALLY-TOP-LEVEL would make LOCALLY also "pass
through" top-level-ness to its body. The reason why that is not
addressed in this issue is that it involves making LOCALLY a special
form.
Pitman and Moon don't care whether we say `top level,' `top-level,' or
`toplevel.' The spelling choices in this writeup are arbitrary. If
necessary, the proposal GENERALIZE-EVAL-NEW-KEYWORDS could be amended
to propose :COMPILE-TOP-LEVEL, etc.
Pitman, Moon, and Bob Laddaga (a Symbolics Cloe implementor) support
both of these proposals. Pitman and Laddaga have a preference for
GENERALIZE-EVAL-NEW-KEYWORDS. Moon is neutral about which should be
preferred.
Sandra Loosemore says:
I still feel somewhat uncomfortable with the definition of EVAL-WHEN
presented here, mostly because its nesting behavior is so unintuitive
(as in test case number 6). We have also had a hard time in deciding
what the term "top-level" really means; the definition presented here
is rather arbitrary. However, since we have run out of time in which
to come up with acceptable alternatives, I'm willing to go along with
proposal GENERALIZE-EVAL. It is compatible with the description in
CLtL but presented in a more coherent way, and I think it is an
improvement. On the other hand, I don't really like the idea of
changing the names of the keywords; if we are going to make an
incompatible change, the right thing to do would be to throw out
EVAL-WHEN entirely and start from scratch.
Treating MACROLET and SYMBOL-MACROLET (and possibly LOCALLY)
complicates the treatment of top-level DEFMACROs and other
defining macros that cause functions to be created at compile-time
(because the lexical environment the functions are defined in may
not be null). See issue DEFINING-MACROS-NON-TOP-LEVEL for details.-------
∂23-Mar-89 1538 CL-Cleanup-mailer The Revised Cleanup Issue Status List
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:33:50 PST
Received: from Semillon.ms by ArpaGateway.ms ; 23 MAR 89 13:44:52 PST
Date: 23 Mar 89 13:43 PST
From: masinter.pa@Xerox.COM
to: cl-cleanup@sail.stanford.edu
Subject: The Revised Cleanup Issue Status List
to: X3J13@sail.stanford.edu
Message-ID: <890323-134452-5540@Xerox>
This is the revised (as of 23-Mar-89 13:43:08) complete list of
Cleanup issues that are either:
passed: passed at *any* previous meeting, including Jan 89
pending: have been distributed for the March meeting
in progress: might possibly be distributed for the March meeting,
or that I think are worth pursuing.
Of course, some more might come up or be revived.
I think I have updated versions of all pending and passed
issues stored on arisia.xerox.com under the
clcleanup/pending
clcleanup/passed
directories respectively.
Codes:
! released for Jan 89 meeting
+ passed
* need new version
!*: released, but I know we'll need a new version
+*: passed, but need to reconsider
!*: passed, but need a new version to reconsider
!
+ ADJUST-ARRAY-DISPLACEMENT
Version 4, 23-Nov-87
Status: passed, 1988
+ ADJUST-ARRAY-FILL-POINTER
Version 1, 15-MAR-88
Status: passed, 1988
! ADJUST-ARRAY-NOT-ADJUSTABLE
Synopsis: ADJUST-ARRAY on array made with :ADJUSTABLE NIL: "an error"?
Version 4, 11-Jan-89, Released 12-Jan-89
Status: Accepted with amendments Jan 89 X3J13
Comments: amendment had wording problem.
Version 8, 11-Mar-89, Released 15-Mar-89
Version 9, 17-Mar-89, released 21-mar-89
Comments: (whew!)
Status: ready for vote
+ APPLYHOOK-ENVIRONMENT
Synopsis: remove (useless) env argument to applyhook
Version 2, 10-Jan-89, Released 10-Jan-89
Status: Passed Jan-89 X3J13
+ AREF-1D
14-NOV-87, Version 7
Status: Passed, 1988?
+ ARGUMENTS-UNDERSPECIFIED
Synopsis: Clarify various ranges missing from CLtL
Version 4, 21-Sep-88, Released 4 Dec 88
Status: Passed Jan 89 X3J13
+ ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS
Synopsis: What do array element-type declarations mean?
Version 9, 31-Oct-88, Released 5 Dec 88
Status: Passed Jan 89 X3J13
+ ASSOC-RASSOC-IF-KEY
Version 4, 23-NOV-87
Status: Passed, 1988?
! BREAK-ON-WARNINGS-OBSOLETE
Synopsis: deprecate *BREAK-ON-WARNINGS* because of *BREAK-ON-SIGNALS*
Version 1, 07-Mar-89, Released 15-Mar-89
Comment: leaves out a case
Status: ready for vote
! CLOS-CONDITIONS
Version 4, 10-Mar-89
Comments: define metaclass of conditions?
Status: pending
+ CLOSE-CONSTRUCTED-STREAMS
Synopsis: What does it mean to CLOSE a constructed stream?
Version 2, 12-Jan-89, Released 12-Jan-89
Status: Proposal ARGUMENT-STREAM-ONLY passed Jan 89 X3J13
!+ CLOSED-STREAM-OPERATIONS
Synopsis: What operations are legal on closed streams?
Version 5, 5-Dec-88, released 5-Dec-88
Status: amended at meeting
Version 7, 14-Feb-89
Status: Passed, as amended, Jan 89 X3J13
Comment: amendment bad; reconsider version 5.
say that INPUT-STREAM-P and OUTPUT-STREAM-P
are undefined on closed streams?
! COERCE-INCOMPLETE
Synopsis: Extend COERCE
Version 3, 7-Mar-89, Released 14-Mar-89
Status: ready for voting
+ COLON-NUMBER
Synopsis: :123 is an error
22-OCT-87, Version 1
Status: Passed, 1988?
! COMMON-TYPE
Version 1, 20-Mar-89, released 21-Mar-89
Status: vote
! COMPLEX-RATIONAL-RESULT
Version 1, 20-Mar-89, released 21-Mar-89
Status: vote
+ COMPILER-WARNING-STREAM
Version 6, 5-JUN-87
Status: Passed, 1988?
+ COMPLEX-ATAN-BRANCH-CUT
Synopsis: tweak upper branch cut in ATAN formula
Version 1, 13-Dec-88, Released 10-Jan-89
Status: Passed Jan 89 X3J13
!* CONDITION-RESTARTS
Synopsis: can't know whether restart is associated with signalling
Version 1, 18-Jan-89, released 16-Mar-89
Comment: (proposed amendments)
Status: need new version
+ CONTAGION-ON-NUMERICAL-COMPARISONS
Version 1, 14-Sep-88, Released 6 Oct 88
Status: passed, Jan 89 X3J13
! COPY-SYMBOL-COPY-PLIST
Version 1, 10-Jan-89, released 16-Mar-89
Status: ready for vote
! COPY-SYMBOL-PRINT-NAME
Version 2, 15-Mar-89, released 16-Mar-89
Status: ready for vote
+ DATA-TYPES-HIERARCHY-UNDERSPECIFIED
4-SEP-88 Version 2
Status: Passed, 1988?
+ DECLARATION-SCOPE
Version 4, 15-Nov-88, Released 9-Dec-88
Status: NO-HOISTING passed Jan 89 X3J13
+ DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES
Version 3, 13-Jan-89
Status: passed, Jan 89 X3J13
+ DECLARE-FUNCTION-AMBIGUITY
Version 4, 5-Dec-88, Released 5-Dec-88
Status: passed, Jan 89 X3J13
+ DECLARE-MACROS
5-FEB-88, Version 3
Status: Passed, 1988?
+ DECLARE-TYPE-FREE
Version 10, 12-Jan-89
Status: proposal LEXICAL passed Jan 89 X3J13
+ DECODE-UNIVERSAL-TIME-DAYLIGHT
Version 2, 30-Sep-88, Released 6 Oct 88
Status: Passed, Jan 89 x3j13
* DEFMACRO-LAMBDA-LIST
Version 2, 17-Mar-89
Status: ** NEED NEW VERSION **
+ DEFPACKAGE
Version 7, 2-Nov-88, Released 5 Dec 88
Comment: clarify "at variance" in editorial work?
Status: Passed, Jan 89 X3J13
+ DEFSTRUCT-CONSTRUCTOR-KEY-MIXTURE
Version 3, 8-Jan-89, Released 11-Jan-89
Status: Passed, Jan 89 X3J13
+ DEFSTRUCT-DEFAULT-VALUE-EVALUATION
Version 1, 5/13/88
Status: Passed, 1988
+ DEFSTRUCT-PRINT-FUNCTION-INHERITANCE
Version 3, 7 Dec 88, Released 12-Dec-88
Status: Passed, Jan 89 X3J13
+ DEFSTRUCT-REDEFINITION
Synopsis: what happens if you redefine a DEFSTRUCT?
Version 3, 6-Feb-89
Status: Passed (as amended) Jan 89 X3J13
+ DEFSTRUCT-SLOTS-CONSTRAINTS-NAME
Version 5, 12-Jan-89
Status: Passed, Jan 89 X3J13
+ DEFSTRUCT-SLOTS-CONSTRAINTS-NUMBER
Version 1, 5/13/88
Status: Passed, 1988
+ DEFVAR-DOCUMENTATION
23-NOV-87, Version 2
Status: Passed, 1988?
+ DEFVAR-INIT-TIME
29-MAR-87, Version 2
Status: Passed, 1988?
+ DEFVAR-INITIALIZATION
Version 4 5-JUN-87
Status: Passed, 1988?
+ DESCRIBE-INTERACTIVE
Version 4, 15-Nov-88, Released 7-Dec-88
Synopsis: can DESCRIBE ask user a question?
Status: Proposal NO passed Jan 89 X3J13
! DESCRIBE-UNDERSPECIFIED
Version 1, 10-Mar-89, Released 16-Mar-89
Synopsis: making DESCRIBE generic was wrong; fix
Comments: "and calls DESCRIBE recursively argument if there are ... "
status: need to strike "argument"; then vote
!* DESTRUCTURING-BIND
Version 2, 25-Jan-89, Released 16-Mar-89
Synopsis: add DESTRUCTURING-BIND macro
Comments: (at end) + "can't extend by defining harmless...????"
Status: might need new version before vote
+ DISASSEMBLE-SIDE-EFFECT
Version 3 1/21/88
Status: Passed, 1988
+ DO-SYMBOLS-DUPLICATES
Version 3 23-NOV-87
Status: Passed, 1988?
+ DOTTED-MACRO-FORMS
Version 3, 15-Nov-88, Released 7-Dec-88
Status: passed, Jan 89 X3J13
+ DRIBBLE-TECHNIQUE
14-FEB-88, Version 2
Status: Passed, 1988?
! DYNAMIC-EXTENT
Version 3, 11-Jan-89, released 16-Mar-89
Comments: still some holes
Status: ready for vote?
+ EQUAL-STRUCTURE
Version 6, 11-Jan-89, Released 12-Jan-89
Status: Passed with amendments
Version 7, 15-Mar-89
Status: Passed Jan 89 X3J13 as amended.
* EQUALP-GENERIC
Version 1, 28-Feb-89
Synopsis: make EQUALP generic function
Comments: Various problems being worked on
Status: ** NEED NEW VERSION ***
* ERROR-CHECKING-IN-NUMBERS-CHAPTER
Version 1, 6-Mar-89
Synopsis: define 'should signal', 'might signal' for number fns
Status: ** NEED NEW VERSION **
! ERROR-NOT-HANDLED
Version 1, 25-Sep-88, Released 6-Oct-88 and 14-Mar-89
Status: ready for vote
+ EVAL-OTHER
8-JUN-88, Version 2
Status: Passed, 1988?
! EXIT-EXTENT
Version 6, 8-Jan-89, distributed at Jan89 X3J13
Rereleased 16-Mar-89
Status: tabled Jan89; ready for vote
+ EXPT-RATIO
Version 3, 31-Oct-88, Released 7 Dec 88
Status: passed, Jan 89 X3J13
+ FIXNUM-NON-PORTABLE
Version 4, 7-Dec-88, Released 12-Dec-88
Version 6, 17-Mar-89, as amended
Status: Passed, Jan 89 X3J13, as amended
+ FLET-DECLARATIONS
Version 2, 2 FEB 88
Status: Passed, 1988?
+ FLET-IMPLICIT-BLOCK
Version 6 5-JUN-87
Status: Passed, 1988?
+ FORMAT-ATSIGN-COLON
Version 4 5-JUN-87
Status: Passed, 1988?
+ FORMAT-COLON-UPARROW-SCOPE
Version 3, 5 FEB 88
Status: Passed, 1988?
+ FORMAT-COMMA-INTERVAL
Version 2, 15-JUN-87
Status: Passed, 1988?
+ FORMAT-E-EXPONENT-SIGN
Version 2, 2 Oct 88, Released 6 Oct 88
Status: Passed, Jan 89 X3J13
+ FORMAT-OP-C
11-JUN-87, Version 5
Status: Passed, 1988?
* FORMAT-PLURALS
Synopsis: remove ~P, add ~:@[singular~;plural~]
Status: no proposal
+ FORMAT-PRETTY-PRINT
Version 7, 15 Dec 88, Released 7 Dec 88
Comments: passed, Jan 89 X3j13
+ FUNCTION-CALL-EVALUATION-ORDER
Version 1, 22-MAR-88
Status: Passed, 1988
! FUNCTION-COERCE-TIME
Synopsis: When does SYMBOL-FUNCTION happen in MAPCAR?
Version 2, 16-sep-88, Released 8-Oct-88
Re-released: 16-Mar-89
Status: ready for vote?
+ FUNCTION-COMPOSITION
Synopsis: Add new functions
Version 5, 10-Feb-89
Status: Passed (as amended) Jan 89 X3J13
maybe this was passed as amendment to TEST-NOT-IF-NOT instead
+ FUNCTION-DEFINITION
Version 3, 10-Feb-89
Status: Passed (as amended) Jan 89 X3J13
! FUNCTION-NAME
Comment: renaming of SETF-FUNCTION-VS-MACRO, SETF-PLACES
SETF-FUNCTION-VS-MACRO
Version 3, 4-Nov-87, Released Nov 87
SETF-PLACES
Version 1, 11-Nov-88, Released 9-Dec-88
FUNCTION-NAME
Version 1, 27-Jan-89, Released 16-Mar-89
Status: ready for vote
+ FUNCTION-TYPE
Version 12, 4-SEP-88
Status: Passed, June 1988 X3J13, as amended
+ FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS
Synopsis: Change semantics of argument types in function declarations
Version 3, 7-Dec-88, Released 12-Dec-88
Status: Passed, Jan 89 X3J13
+ FUNCTION-TYPE-KEY-NAME
Version 3, 13-FEB-88
Status: Passed, 1988
+ FUNCTION-TYPE-REST-LIST-ELEMENT
Version 5, 14-Nov-88, Released 8-Dec-88
Status: Passed, Jan 89 X3J13
! GENSYM-NAME-STICKINESS
Synopsis: no side effects if optional arg supplied
Version 1, 14-Feb-89, Released 14-Mar-89
Status: comments
Version 3, 20-Mar-89
Status: vote?
+ GET-MACRO-CHARACTER-READTABLE
Version 3, 11-Feb-89
Status: Passed (as amended) Jan 89 X3J13
+ GET-SETF-METHOD-ENVIRONMENT
Version 5 13-JUL-87
Status: Passed, 1988?
! HASH-TABLE-ACCESS
Synopsis: Add new accessors for hash-table properties
Version 1, 13-Sep-88 released 8-Oct-88
Version 2, 13 Oct 88, released 16-Mar-89
status: vote
+ HASH-TABLE-PACKAGE-GENERATORS
Version 7, 8-Dec-88, Released 9-Dec-88
Comments: The test-package-iterator example has the values
from the generator in the wrong order.
Status: passed, Jan 89 X3J13
* HASH-TABLE-PRINTED-REPRESENTATION
Version 2, 8-Jun-88
Comments: Use #S(ARRAY ...), #S(HASH-TABLE...), #S(PATHNAME...)?
Status: need new proposal
! HASH-TABLE-SIZE
Version 1, 20-Mar-89, released 21-Mar-89
+ HASH-TABLE-TESTS
Version 2, 8-Dec-88, Released 8 Dec 88
Status: passed Jan 89 X3J13
+ IEEE-ATAN-BRANCH-CUT
Version 2, 11-Jan-89, Released 11-Jan-89
Status: passed, Jan 89 X3J13
* IGNORE-VARIABLE
Synopsis: default (IGNORE IGNORE)
Version 1, 6-Feb-89
+ IMPORT-SETF-SYMBOL-PACKAGE
Version 5 ??-MAY-87
Status: Passed, 1988?
! IN-PACKAGE-FUNCTIONALITY
Version 4, 12-Dec-88, Released 12-Dec-88
Status: tabled
Version 8, 15-Mar-89, Released 15-Mar-89
Status: ready for vote
+ KEYWORD-ARGUMENT-NAME-PACKAGE
8-NOV-87, Version 8
Status: Passed, 1988?
+ LAST-N
12-MAR-88, Version 2
Status: Passed, 1988?
+ LCM-NO-ARGUMENTS
Version 1, 17 Oct 88, Released 8 Dec 88
Status: passed, Jan 89 X3J13
! LISP-PACKAGE-NAME
Synopsis: change LISP to COMMON-LISP to avoid CLtL confusion
Version 1, 22 Dec 88, Released 11-Jan-89
Status: tabled; version 1 still ready for vote
! LISP-SYMBOL-REDEFINITION
Version 5, 22-Nov-88, Released 8 Dec 88
Comments: Don't like (DEFVAR CAR ...) example
14: Like simpler "Redefining any documented
definition on a symbol in the LISP package -- such as variables,
functions, constants, properties and property-lists, etc -- is
undefined, except for the explicitly allowed cases (e.g. dynamic
binding of variables)."
Status: tabled; version 5 still ready for vote
! LOAD-OBJECTS
Synopsis: Provide a way to allow defstruct/defclass objects in compiled files
Version 3, 9-Mar-89, released 16-Mar-89
Comments: How about MAKE-LOAD-FORM-SAVING-SLOTS?
Status: ready for vote w/ name change?
! LOAD-TRUENAME
Synopsis: Make default pathname for LOAD inside LOAD same?
Version 1, 13-Mar-89, Released 16-Mar-89
Status: ready for vote
! LOCALLY-TOP-LEVEL
Version 2, 16-Mar-89, released 17-Mar-89
Status: ready to vote
! LOOP-AND-DISCREPANCY
Version 1, 15-Mar-89, released 16-Mar-89
status: ready for vote
+ MACRO-FUNCTION-ENVIRONMENT
Version 2, 8-JUN-88
Status: Passed, 1988
* MACRO-SPECIAL-FORMS
Synopsis: macros => implementation-dependent special forms doesn't work
Status: *** NEED PROPOSAL SUBMITTED ****
+ MAKE-PACKAGE-USE-DEFAULT
Version 2, 8 Oct 88, Released 12-Dec-88
Version 3, 16-Mar-89
Status: Passed, Jan 89 X3J13 as amended
! MAKE-STRING-FILL-POINTER
Synopsis: extend MAKE-STRING to take a fill-pointer?
Version 1, 20-Oct-88, released 16-Mar-89
Status: ready for vote
+ MAPPING-DESTRUCTIVE-INTERACTION
Version 2, 09-Jun-88, Released 8 Oct 88
Synopsis: [don't] define interaction of DELETE on MAPCAR'd list.
Status: passed, Jan 89 X3J13
+ NTH-VALUE
Version 4, 8-Dec-88, Released 8 Dec 88
Comment: amended to clarify when index out of range
Version 5, 17-Mar-89
Status: passed, as amended
+ PACKAGE-CLUTTER
Version 6, 12-Dec-88, Released 12-Dec-88
Comments: Accepted, with amendment
Version 7, 17-Mar-89
Status: Passed, Jan 89 X3J13, as amended
+ PACKAGE-DELETION
Version 5, 21 nov 88, Released 8 Dec 88
Comments: Minor glitches? Remove the description of "correctable" error to be signalled and
handled.
Status: passed, Jan 89 X3J13
!+ PACKAGE-FUNCTION-CONSISTENCY
Synopsis: allow strings for package arg everywhere uniformly
Version 2, 12-Jan-89, Released 12-Jan-89
Comment: Accepted MORE-PERMISSIVE with amendments
Version 3, 17-Mar-89, released 17-Mar-89
Status: vote to accept wording as intent of amendment
* PATHNAME-CANONICAL-TYPE
Synopsis: allow canonical :SOURCE-LISP to MAKE-PATHNAME;
require PATHNAME-TYPE to return same?
Version 1, 07-Jul-88
Comments: only add the :TYPE :SOURCE-LISP, not PATHNAME-CANONICAL-TYPE?
Status: => "pathname" committee?
! PATHNAME-COMPONENT-CASE
Version 2, 22-Mar-89, released 22-Mar-89
Status: vote???
! PATHNAME-COMPONENT-VALUE
Version 1, 20-Mar-89, released 21-Mar-89
Status: vote?
* PATHNAME-LOGICAL
Synopsis: add logical pathnames (pathnames for an imaginary portable
file system, which get translated by site-dependent translations into
physical pathnames on an actual file system)
Status: no proposal yet
* PATHNAME-PRINT-READ
Synopsis: Print pathnames like #P"asdf"?
Version 1, 21-Oct-88
Comments: Numerous, pro, con. Print like #S(pathname ...)?
Status: *** NEED NEW VERSION ***
+ PATHNAME-STREAM
Version 6 14-NOV-87
Status: Passed, 1988?
! PATHNAME-SUBDIRECTORY-LIST
Version 4, 22-Mar-89, released 22-mar-89
+ PATHNAME-SYMBOL
Version 5 5-FEB-88
Status: Passed, 1988?
* PATHNAME-SUBDIRECTORY-LIST
Synopsis: How to deal with subdirectory structures in pathname functions
Version 3, 29-Dec-88
Comments: typos and proposed simplifications
Status: *** NEED NEW VERSION ***
* PATHNAME-SYNTAX-ERROR-TIME
Synopsis: when are errors in pathnames detected?
Version 1, 7-Jul-88
Comments: various
Status: need new version? ==> ERRORS-IN-FILE-CHAPTERS?
+ PATHNAME-UNSPECIFIC-COMPONENT
Synopsis: More extensions to :UNSPECIFIC
Version 1, 29-Dec-88, Released 12-Jan-89
Version 2, 17-Mar-89
Status: Passed, Jan 89 X3j13, as amended
+ PEEK-CHAR-READ-CHAR-ECHO
Version 3, 8-Oct-88, Released 8 Oct 88
Synopsis: PEEK-CHAR, READ-CHAR on streams made by MAKE-ECHO-STREAM
Status: Passed, Jan 89 X3J13
* PRETTY-PRINT-INTERFACE
Version 3, 15-Mar-89
Synopsis: standardize interface to prettyprinter
Status: Need new version
+ PRINC-CHARACTER
29-APR-87, Version 2
Status: Passed, 1988?
* PRINT-CIRCLE-SHARED
Synopsis: does *PRINT-CIRCLE* cause shared structure to print with #=?
Status: Not submitted yet ** NEED WRITEUP **
+ PRINT-CIRCLE-STRUCTURE
Version 3, 20 Sep 88, Released 8 Oct 88
Comments: Accepted, with amendment
Version 4, 17-Mar-89
Status: Passed, Jan 89 X3J13, as amended
! PROCLAIM-LEXICAL
Version 9, 8-Dec-88, Released 12-Dec-88
Synopsis: add LEXICAL proclaimation
Comments: lengthy mail; amendments at Jan meeting
Status: tabled, vote on version 9 (w/o amendments)
+ PUSH-EVALUATION-ORDER
Version 5, 25-NOV-87
Status: Passed, 1988?
+ RANGE-OF-COUNT-KEYWORDS
Version 3, 9-Oct-88, Released 14-Oct-88
Status: passed, Jan 89 X3J13
+ RANGE-OF-START-AND-END-PARAMETERS
Version 1, 14-Sep-88, Released 7 Oct 88
Status: passed, Jan 89 X3J13
* READ-CASE-SENSITIVITY
Synopsis: Allow readtables to be case sensitive
Comments: use function or keyword?
Status: need new version
* READ-DELIMITED-LIST-EOF
Synopsis: eof in read deliminted list signals an error
Status: awaiting submission
! REAL-NUMBER-TYPE
Synopsis: add REAL = (OR RATIONAL FLOAT) & range
Version 3, 13-Jan-89, released 16-Mar-89
Status: vote?
+ REDUCE-ARGUMENT-EXTRACTION
Version 3 13-FEB-88
Status: Passed, 1988?
! REMF-DESTRUCTION-UNSPECIFIED
Synopsis: Specification of side-effect behavior in CL
Version 4, 29-Nov-88, Released 12-Jan-89
Status: straw vote in favor of this, BarMar will make amendments
Version 6, 17-Mar-89
Status: ready for vote?
+ REQUIRE-PATHNAME-DEFAULTS
Version 6, 9 Dec 88, Released 09 Dec 88
Status: passed, Jan 89 X3j13
+ REST-LIST-ALLOCATION
Version 3, 12-Dec-88, Released 12-Dec-88
Status: proposal MAY-SHARE passed, Jan 89 X3J13
+ RETURN-VALUES-UNSPECIFIED
Version 6, 9 Dec 88, Released 9-Dec-88
Status: passed, Jan 89 X3J13
+ ROOM-DEFAULT-ARGUMENT
Version 1, 12-Sep-88, Released 8 Oct 88
Status: passed, Jan 89 X3J13
! SETF-MULTIPLE-STORE-VARIABLES
Synopsis: Allow multiple "places" in SETF stores
Version 2, 22-Mar-89, released 22-Mar-89
Status: ready for vote?
+ SETF-SUB-METHODS
Version 5, 12-Feb-88, Released 8 Oct 88
Synopsis: careful definition of order inside (SETF (GETF ...) ...)
Status: passed, Jan 89 X3J13
+ SHADOW-ALREADY-PRESENT
Version 4 10-NOV-87
Status: Passed, 1988?
+ SHARPSIGN-PLUS-MINUS-PACKAGE
Version 3 14-NOV-87
Status: Passed, 1988?
+ SPECIAL-TYPE-SHADOWING
Synopsis: intersection of types when proclaimed special has local type
declaration
Version 1, 4-Nov-88, released 11-Jan-89
Status: passed, Jan 89 X3J13
+ STANDARD-INPUT-INITIAL-BINDING
Version 8, 8 Jul 88, Released 7 Oct 88
Status: passed, Jan 89 X3J13
+ STEP-ENVIRONMENT
Version 3, 20-Jun-88, Released 7 Oct 88
Version 4, 17-Mar-89
status: Passed, Jan 89 X3J13, as amended
+ STREAM-ACCESS
Version 2, 30-Nov-88, Released 9 Dec 88
Status: ADD-TYPES-ACCESSORS passed, Jan 89 X3J13
+ SUBSEQ-OUT-OF-BOUNDS
29-MAR-88 Version 2
Status: Passed, 1988?
* SUBTYPEP-ENVIRONMENT
Version 1, 2-Jan-89
Status: ** missing writeup ***
+ SUBTYPEP-TOO-VAGUE
Version 4, 7-Oct-88, Released 7 Oct 88
Status: passed, Jan 89 X3J13
+ SYMBOL-MACROLET-DECLARE
Version 2, 9-Dec-88, Released 9 Dec 88
Status: passed, Jan 89 X3J13
!+ SYMBOL-MACROLET-SEMANTICS
Version 5, 30-Nov-88, Released 9 Dec 88
Status: Passed, Jan 89 X3J13
Version 6, 14-Mar-89, released 16-Mar-89
Status: ready for vote
+ TAILP-NIL
Version 5, 9-Dec-88, Released 12-Dec-88
Synopsis: Operation of TAILP given NIL
Status: passed, Jan 89 X3J13
+ TEST-NOT-IF-NOT
Version 3, 1 Dec 88, Released 9 dec
Version 4, 18-Mar-89
Status: Need new version as amended.
! THE-AMBIGUITY
Version 2, 11-Jan-89, Released 11-Jan-89
Comments: typo, sense wrong
Status: tabled, vote on 2
! TIME-ZONE-NON-INTEGER
Version 1, 13-Mar-89, Released 16-Mar-89
Status: ready for vote
+* TYPE-OF-UNDERCONSTRAINED
Version 3, 12-Dec-88, Released 12 Dec 88
Comments: Accepted, with amendments
Version 5, 16-Mar-89
Comments: constraints wrong
Status: ** NEED NEW VERSION ***
! UNDEFINED-VARIABLES-AND-FUNCTIONS
Synopsis: What happens on an undefined function call, unbound variable ref?
Version 1, 29-Nov-88, Released 11-Jan-89
Comments: Lumping SLOT-UNBOUND in with unbound special variables was a mistake,
as SLOT-UNBOUND is an extension mechanism, not only a safety checking
mechanism. Also there were some wording problems. Gabriel and Gregor
are to submit a revised proposal.
No version arrived.
Status: vote on 1?
+ UNREAD-CHAR-AFTER-PEEK-CHAR
Version 2, 2-Dec-88, Released 12-Dec-88
Status: passed, Jan 89 X3J13
+ VARIABLE-LIST-ASYMMETRY
Version 3, 08-Oct-88, Released 9 Dec 88
Status: passed, Jan 89 X3J13
+ WITH-OUTPUT-TO-STRING-APPEND-STYLE
Version 5, 7-JUN-88
Status: Passed, 1988?
! WITH-OPEN-FILE-DOES-NOT-EXIST
Version 1, 17-Mar-89
Status: ready?
∂23-Mar-89 1657 X3J13-mailer cl-compiler issue status as of Mar 23
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89 16:23:32 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA18840; Thu, 23 Mar 89 16:53:11 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA12850; Thu, 23 Mar 89 16:53:08 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232353.AA12850@defun.utah.edu>
Date: Thu, 23 Mar 89 16:53:06 MST
Subject: cl-compiler issue status as of Mar 23
To: x3j13@sail.stanford.edu
Here is the current list of active cl-compiler issues. I have mailed
out revised versions of most of the issues where we got some specific
comments on the previous version, and I've noted other comments below.
There will be hardcopies of all of the latest and greatest writeups
available at the meeting. I'm not anticipating that we will be
producing another round of revisions before then, so if you want
something changed, please be prepared to present an amendment at the
meeting.
CLOS-MACRO-COMPILATION (version 3)
Clarify compile-time behavior of CLOS defining macros.
Proposal MINIMAL
Proposal NOT-SO-MINIMAL
[New version distributed in response to comments.]
COMPILE-ENVIRONMENT-CONSISTENCY (version 5)
What kinds of things can/must the compiler "wire in" to the code
it compiles?
Proposal CLARIFY
[New version distributed in response to comments.]
COMPILE-FILE-SYMBOL-HANDLING (version 2)
How does COMPILE-FILE tell LOAD what package to put symbols in?
Proposal CURRENT-PACKAGE
Proposal HOME-PACKAGE
Proposal REQUIRE-CONSISTENCY
[Some people want to leave this unspecified.]
COMPILED-FUNCTION-REQUIREMENTS (version 5)
What does the COMPILED-FUNCTION type imply? Do COMPILE and
COMPILE-FILE construct COMPILED-FUNCTIONs?
Proposal TIGHTEN
Proposal TIGHTEN-COMPILE
Proposal FLUSH
[New version distributed in response to comments.]
COMPILER-DIAGNOSTICS (version 10)
Clarify status and handling of errors and warnings signalled during
compilation.
Proposal USE-HANDLER
[New version distributed in response to comments.]
COMPILER-LET-CONFUSION (version 8)
The description of COMPILER-LET in CLtL is broken -- should we fix
it or eliminate it entirely?
Proposal REPAIR
Proposal ELIMINATE
[New version distributed in response to comments.]
COMPILER-VERBOSITY (version 6)
Mechanisms for controlling progress messages issued by the compiler.
Proposal LIKE-LOAD
CONSTANT-CIRCULAR-COMPILATION (version 8)
Must circular or recursive objects be compiled correctly? Must the
compiler preserve sharing of substructures?
Proposal NO
Proposal PRESERVE-SHARING-ONLY
Proposal YES
[New version distributed in response to comments.
Expect amendment to change error terminology.]
CONSTANT-COLLAPSING (version 6)
Should the compiler be allowed to "collapse" or coalesce constants
that satisfy a more general equivalence relationship than EQUAL?
Proposal GENERALIZE
[New version distributed in response to comments.]
CONSTANT-COMPILABLE-TYPES (version 9)
What types of objects can appear as quoted or self-evaluating constants
in compiled code?
Proposal SPECIFY
[New version distributed in response to comments.]
CONSTANT-FUNCTION-COMPILATION (version 1)
What do we do about quoted function constants?
Proposal NO
[This is a new issue, split off from CONSTANT-COMPILABLE-TYPES. We
are willing to consider alternate proposals.]
DEFCONSTANT-NOT-WIRED (**DRAFT** version 6)
How do you declare a variable to be constant without giving the
compiler permission to make assumptions about its value?
[None of the proposals are ready to be voted on. This issue
is being distributed only for informational purposes.]
DEFINE-OPTIMIZER (version 6)
Provide a macro-like way of specifying source-level optimizations
on function calls.
Proposal NEW-FACILITY
[New version distributed in response to comments.]
DEFINING-MACROS-NON-TOP-LEVEL (version 9)
Are defining macros such as DEFUN meaningful in non-top-level locations?
Proposal ALLOW
[New version distributed in response to comments.]
EVAL-WHEN-NON-TOP-LEVEL (version 7)
What does EVAL-WHEN mean when it appears in non-top-level locations?
Proposal GENERALIZE-EVAL
Proposal GENERALIZE-EVAL-NEW-KEYWORDS
[New version distributed in response to comments.]
LOAD-TIME-EVAL (version 11)
Add a new special form, LOAD-TIME-VALUE.
Proposal R**2-NEW-SPECIAL-FORM
Proposal R**3-NEW-SPECIAL-FORM
[Proposal R**2-NEW-SPECIAL-FORM was approved at the January meeting,
but some additional suggestions were made after the meeting.]
MACRO-CACHING (version 2)
Is it legitimate to cache macro expansions?
Proposal DISALLOW
Proposal RESTRICT
[Moon suggested the presentation could be simplified.]
MACRO-ENVIRONMENT-EXTENT (**DRAFT** version 3)
Do environment objects received as the &ENVIRONMENT argument to a
macro have dynamic or indefinite extent?
Proposal INDEFINITE
Proposal DYNAMIC
Proposal DYNAMIC-WITH-COPIER
[Barmar wants the copier function renamed (to what?)]
PROCLAIM-ETC-IN-COMPILE-FILE (**DRAFT** version 4)
Are top-level calls to PROCLAIM handled specially by the compiler?
Proposal YES
Proposal NO
Proposal NEW-MACRO
[New name for DEFPROCLAIM?]
QUOTE-SEMANTICS (version 3) (replaces QUOTE-MAY-COPY)
May COMPILE and EVAL construct equivalent copies of quoted or
self-evaluating constants, or must constants share structure with
the source code for the program? Do the constraints on what objects
are valid constants also apply to COMPILE and EVAL, or only to
COMPILE-FILE?
Proposal NO-COPYING
Proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS
Proposal SAME-AS-COMPILE-FILE
[New version distributed in response to comments.]
SAFE-CODE (version 1)
What does the term "safe code" mean?
Proposal SAFETY-3
[This issue has been withdrawn.]
SYNTACTIC-ENVIRONMENT-ACCESS (version 6)
Provide accessors and constructors for lexical environment objects.
Proposal SMALL
[New version distributed in response to comments.]
WITH-COMPILATION-UNIT (version 3)
Provide a way to compile a group of files as a unit for the purposes
of error messages.
Proposal NEW-MACRO
[There have been complaints that the proposal is not ready to be
voted on.]
-------
∂23-Mar-89 1656 X3J13-mailer Issue: PATHNAME-COMPONENT-VALUE (version 1)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 23 Mar 89 15:52:13 PST
Received: from pitney-bowes ([192.9.200.50]) by heavens-gate.lucid.com id AA03552g; Thu, 23 Mar 89 12:36:58 PST
Received: by pitney-bowes id AA26463g; Thu, 23 Mar 89 12:35:22 PST
Date: Thu, 23 Mar 89 12:35:22 PST
From: Jim McDonald <jlm@lucid.com>
Message-Id: <8903232035.AA26463@pitney-bowes>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: X3J13@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Tue, 21 Mar 89 17:52 EST <19890321225242.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-COMPONENT-VALUE (version 1)
PATHNAME-COMPONENT-VALUE:SPECIFY seems seriously flawed to me. I give
some reasons, a sktech of a strawman alternative, and some options to
consider. Pardon the length, but the issue is one of the messiest that
CL must deal with. If you're really pressed, search for "given all".
My particular concern is that by restricting pathname-names, for
example, to be strings, PATHNAME-COMPONENT-VALUE:SPECIFY hides the
semantics associated with a pathname behind host-specific string
parsing rules. ("Structured" names are forbidden.) My comments will
refer to pathname-names, but similar arguments should apply for
pathname-types and elements of directory lists.
Part of the rationale says:
Removing "structured" names should improve portability without causing
any harm, assuming no implementation uses structured names. This will
improve portability by allowing programs to do string manipulation on
names, although such programs still have to be careful since the valid
characters and maximum length of a name are implementation-dependent.
But I fail to see how string manipulation functions are particularly
useful or intuitive when porting the un*x c-shell wildcard name
"/foo/a?b.lisp" into an MVS pathname, where there is no system support
for single-character wildcards. I would rather specify something
like:
(MAKE-PATHNAME :DIRECTORY *source-dir*
:NAME '("a" :WILD-CHARACTER "b")
:EXTENSION "lisp")
and let CL handle the wildcard problem if the OS doesn't.
Also note that the "host" parsing rules may be something as specific
as a shell convention. E.e., un*x filesystems do not treat "*" at
all specially--that is done by the shells. Only a kind of peer
pressure keeps the shells and other utilities fairly consistent on a
given machine.
In spite of the paragraph quoted above from the rationale, I assume
the best motivation for hiding the semantics is to be able to defer
all such semantic questions to the host, to avoid any need to query
the host during normal pathname manipulations. I.e., when a user
types "a$b" for host foo, lisp don't need to query foo to discover
that this is a wildcard template or means burn after reading. (Don't
laugh--the "3" in "FOO LISP A3" for CMS means erase this file as soon
as the first reference is closed, as opposed to "FOO LISP A1" which
means treat this as a normal file, or "FOO LISP A7" which is illegal.)
Overall, I see three generic problems:
(1) To determine if a given pathname-name (e.g. "a$b") is a specific
filename or a template, one needs to invoke some as-yet
unspecified oracle. Something like the proposal
PATHNAME-EXTENSIONS would be needed to address this issue.
(2) To portably make a template to select a given set of filenames,
one needs to consult an unspecified inverse oracle.
>> I've seen no proposal that addresses this problem. <<
E.g., consider the problem of making a template that will match
all filenames on a given directory starting with "a" and ending
with "b". How would I write this??
Or consider the problem of finding all files that match "*foo*"
(using Unix csh conventions), but not "*.lisp". Under the
given proposal, one is forced to use the DIRECTORY function to
get truenames for all the "*.lisp" files before doing the
set-difference. This seems very clumsy and wasteful when
compared to what DIRECTORY could accomplish if it understood
pathnames containing regular expressions.
Also note that some operating systems (e.g. MVS) support the
notion of the "*" wildcard convention (wild string), but not
"?" (wild character). So the proposal mandates that it must be
impossible to portably create a pathname template for names of
three characters starting with "a" and ending with "b".
(3) OS oracles such as those proposed by PATHNAME-EXTENSIONS cannot
hope to address all novel or idiosyncratic features of
file-systems, except in the very weak sense of saying "here be
dragons". More informative oracles would be needed for
portability, so over time we must be prepared to augment the
standard or ports must write ad hoc oracles for things like
"A3" on CMS. This is only vaguely addressed through the
proposals about legal extensions to Common Lisp.
An alternative scheme (admittedly not perfect) would be to standardize
an internal format for things like wildcard templates, e.g.
("a" :WILD-STRING "b"). This addresses the three problems as follows:
(1) The first problem partially goes away--e.g., "a$b" could be
treated unambiguously as a three-character filename, even for
hosts where shells, etc. tend to treat "$" specially.
Templates would be required to be non-atomic objects, perhaps
lists starting with :WILD. (In effect, the oracle at this
level has been reduced to simple standardized rules on obvious
lisp data formats.)
Unfortunately, the problem has been pushed to another level,
since users are presumably typing filenames according to host-
specific conventions which they expect to be honored. Even if
the internal representation becomes largely host-independant,
parse-namestring may need to consult the same oracles mentioned
above to be able to internalize correctly. This could even be
pessimal in putting all of the semantic burden (hence perhaps
file-system queries) up front when it might otherwise be
avoided. In general though, there can be CL code to emulate
most of the parsing that would be done by the filesystem, and
there could be an escape such as (:UNPARSED "a$b"), to allow
parsing to be deferred until necessary.
On the whole, I think something like this alternative scheme
would win on this point.
(2) The second problem goes away (it was the original motivation
for this message). E.g., the rules for making a wildcard are
standardized and portable. (Of course, each implementor then
needs to interpret ("a" :WILD-STRING "b") appropriately, which
might involve the creation of a string like "a$b". But
implementors are trained to deal with such details.)
(3) The third problem comes back with a vengeance, since nothing
would be passed through "as is", and thus novel features by
definition would be prohibited. This could be addressed by
adding an escape that passes things through to the OS for
semantic parsing without CL attempting to understand them. How
users would indicate this option is problematic.
Given all of the above, I think a more flexible proposal for pathnames
would allow the name field (for example) to be structured as at least
any of the following:
"a*b" -- a 3-character filename, or
(:EXPLICIT "a*b") -- a 3-character filename
("a" :WILD-STRING "b") -- a template for filenames string with "a"
and ending with "b"
(:UNPARSED "a*b") -- a filename or template that may require
an OS request to disambiguate (when
parsed, this should yield a standard CL
format)
(:UNINTERPRETED "a*b") -- a filename or template that CL will not
attempt to understand (if used
inappropriately, the consequences are
undefined)
It should be a separate issue which of these (PARSE-NAMESTRING "a*b")
would produce.
PATHNAME-COMPONENT-VALUE:SPECIFY seems to give "a*b" the semantics of
:UNINTERPRETED and forbid all other options. Personally, I would
prefer to give "a*b" the semantics of :EXPLICIT and allow at least
these four options.
The rules for parse-namestring require more thought than I can afford
right now, but I hope this suffices to show that the stated proposal
is, unfortunately, far more problematic than advertized.
jlm
∂23-Mar-89 2100 X3J13-mailer Issue: GENSYM-NAME-STICKINESS (Version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89 21:00:01 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 564017; Thu 23-Mar-89 17:34:54 EST
Date: Thu, 23 Mar 89 17:34 EST
From: CL-Cleanup@SAIL.Stanford.EDU
Sender: KMP@STONY-BROOK.SCRC.Symbolics.COM
Reply-To: CL-Cleanup@SAIL.Stanford.EDU
Subject: Issue: GENSYM-NAME-STICKINESS (Version 3)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323173428.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Issue: GENSYM-NAME-STICKINESS
Forum: Cleanup
References: GENSYM (p169)
Category: CHANGE
Edit history: 14-Feb-89, Version 1 by Pitman
15-Mar-89, Version 2 by Steele (add GENSYM-COUNTER function)
20-Mar-89, Version 3 by Pitman (make it a variable)
Problem Description:
Many people avoid use of the argument to GENSYM because the argument
is `sticky' and such stickiness can lead to confusion. The problem is
that if any application (usually a macro) uses the gensym argument at
all, then all applications are forced to. If they do not, they risk
finding that the `helpful' argument supplied in some previous call will
be harmful to them.
Proposal (GENSYM-NAME-STICKINESS:LIKE-TEFLON)
Define that if an optional argument [either a string or a number] is
given to GENSYM, it does NOT have a side-effect on GENSYM's internal state.
Introduce a new variable, *GENSYM-COUNTER*, which holds the state of
the gensym counter. That is, the next symbol generated by GENSYM will
be number n. The initial value of this variable is not defined, but
must always be a non-negative integer. This variable may be either
assigned or bound by users at any time, but always to a non-negative
integer.
Deprecate the use of a numeric argument to GENSYM.
Rationale:
Conscientious programmers are forced now to write their own GENSYM
lookalikes because they know the system's GENSYM has an invasive
effect. This defeats the primary intended function of GENSYM, which
is to satisfy the most common idiomatic use of MAKE-SYMBOL.
The stickiness of the GENSYM prefix was an attempt to be gratuitously
compatible with Maclisp, at the expense of good programming pratice.
Users who need the old behavior of GENSYM can trivially implement
that behavior using MAKE-SYMBOL.
Occasionally you want to reset the GENSYM counter so that, for example,
you can get the compiler to generate the same symbol names again
(good for comparing results to see what really changed).
Test Case:
;; #1: Test stickiness of name part.
(CHAR-EQUAL (CHAR (SYMBOL-NAME (SECOND (LIST (GENSYM "A") (GENSYM)))) 0)
#\G)
=> NIL ;under CLtL
=> T ;under this proposal
;; #2: Test stickiness of number part.
(= (PARSE-INTEGER (PROGN (GENSYM 6789) (STRING (GENSYM "G"))) :START 1)
6790)
=> T ;under CLtL
=> NIL ;under this proposal (except when *gensym-counter* happens to align)
;; #3: Illustrate use of new variable.
(STRING= (SYMBOL-NAME (LET ((*GENSYM-COUNTER* 43)) (GENSYM "FOO")))
"FOO43")
=> T ;under this proposal (not meaningful previously)
Current Practice:
Symbolics Cloe and Genera are compatible with CLtL, so this would be an
incompatible change.
Cost to Implementors:
Very small.
If any implementations currently use a more compact representation for
the internal state of GENSYM than a variable holding a string and a
separate variable holding an integer, they might be forced to change.
Even then, the change would proabably still be quite small.
Cost to Users:
Most uses of GENSYM do not depend on the stickiness of the name, so the
change would be compatible. In some cases, the change would be an
improvement. Even in the worst case where someone depends on stickiness,
it's extremely straightforward to write the couple of lines of code to
produce an application based on MAKE-SYMBOL that is at least as flexible
as GENSYM, and often moreso.
Cost of Non-Adoption:
Good programmers would avoid using the argument to GENSYM (or using
GENSYM altogether) in many situations where they ought not have to.
Benefits:
Gensyms which appear to convey information through their name would not
accidentally pop out and cause confusion in places where they oughtn't.
Making the gensym counter visible as a variable means that people will
be able to bind the gensym counter locally when they don't want to affect
the global counter.
Aesthetics:
Unnecessary global state changes are hard to reason about. This would
be a small simplification.
Discussion:
Pitman claims to have written a non-sticky GENSYM function for nearly
every one of the dozen or so large systems that he's written or worked
on in the last decade in order to get around the stated problem.
Others have suggested similar experience.
Pitman and Steele support LIKE-TEFLON.
∂23-Mar-89 2059 X3J13-mailer **DRAFT** Issue: PATHNAME-PRINT-READ (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89 20:59:42 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 563865; 23 Mar 89 15:36:42 EST
Date: Thu, 23 Mar 89 15:36 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-PRINT-READ (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323153624.3.KMP@BOBOLINK.SCRC.Symbolics.COM>
>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<
Ponder it and come prepared to discuss it at the meeting.
See summary of Cleanup discussion at end.
-kmp
-----
Issue: PATHNAME-PRINT-READ
References: File System Interface (pp409-427)
Category: CHANGE/ADDITION
Edit history: 21-Oct-88, Version 1 by Pitman
Status: For Internal Discussion
Problem Description:
Although pathnames are required to print re-readably, there is no
standardized representation for pathnames and so no standardized
way in which they should print.
Further, it is common in programs to want pathnames to print in
their file-system specific format.
Proposal (PATHNAME-PRINT-READ:SHARPSIGN-P):
Define the reader syntax #P"..." to be equivalent to
#.(PARSE-NAMESTRING "...").
Define that when *PRINT-ESCAPE* is T, the syntax #P"..." is
how a pathname should be printed by WRITE (and hence by PRIN1,
PRINT, etc.). The "..." is the namestring representation of the
pathname.
Define that when *PRINT-ESCAPE* is NIL, WRITE writes a pathname
object P by writing (NAMESTRING p) instead.
Test Case:
(PARSE-NAMESTRING "foo.lisp")
=> #P"foo.lisp"
(FORMAT NIL "Written to ~A." #P"foo.bin")
=> "Written to foo.bin."
(TYPEP #P"foo.bin" 'PATHNAME)
=> T
Rationale:
This satisfies the stated goals.
[For :ESCAPE T] It will not be possible to make the printed
pathname printed representation totally portable because of
variations in file systems, but for different Common Lisp
implementations on the same file system, or for Common Lisp
systems running on file systems having compatible syntax,
portability would be improved by this specification.
Also, some implementations (eg, Symbolics Genera) use
specialized representations for pathnames on different file
systems. Eg, an MSDOS pathname is of type MSDOS-PATHNAME,
not just type PATHNAME. #S(PATHNAME ...) is not only more
verbose than necessary but might be misleading to some users
because the object created will not have a TYPE-OF PATHNAME.
[For :ESCAPE NIL] Printing the namestring of a pathname is
a common operation and it is convenient to have a shorthand
for doing it. Further, some implementations may be able to
optimize the presentation of a pathname in this mode by
printing it without actually consing the string.
Current Practice:
Symbolics Genera implements the proposed behavior.
Cost to Implementors:
Fairly minor changes to the readtable and the printer.
Cost to Users:
Users who now use the non-portable syntax #S(...) in order
to enter literal pathnames might have to change. [However,
implementations would be free to continue to support this
read syntax for compatibility.]
Cost of Non-Adoption:
Portability of code and data involving pathnames within a
given file system (or between suitably similar file systems)
would be hampered needlessly.
Benefits:
The cost of non-adoption would be avoided.
Aesthetics:
The #P syntax is pretty and hides unimportant details.
Discussion:
Pitman supports this change.
-----
Summary of discussion on CL-Cleanup:
EB noted that Lucid CL implements the proposed behavior and that there
is cost to users who define their own #P read macro. He weakly supports
the proposal but wishes someone had pursued a `generic pathnames' proposal.
Pierson noted that KCL uses #"...", but that this collides with proposed
syntax for Dick Waters' pretty printer. He also thinks #P is better
because it is already more widely used for that purpose.
Masinter noted that Envos Medley prints pathnames with the syntax
#.(pathname "asdf"), which he thinks is not as pretty as #P"asdf"
but currently more portable.
KMP and JonL raised the issues that #. has the disadvantage that it must
be parsed by the full Lisp engine, while #P can be parsed by something
simpler. Permitting #. leaves a gaping hole for trojan horses, and
also requires the presence of the evaluator in a delivery system.
MLY, GSB, Peirson, and IIM argued for not using up an extra dispatch
character.
MLY suggested #S(PATHNAME namestring [optional-host]).
IIM noted they use #.(PATHNAME namestring host) because different file
systems have different parsing conventions.
∂23-Mar-89 2059 X3J13-mailer **DRAFT** Issue: PATHNAME-SYNTAX-ERROR-TIME (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89 20:59:16 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563835; Thu 23-Mar-89 15:19:53 EST
Date: Thu, 23 Mar 89 15:19 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-SYNTAX-ERROR-TIME (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323151934.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<
Ponder it and bring your comments to the meeting.
See summary of CL-Cleanup discussion at end.
-kmp
-----
Issue: PATHNAME-SYNTAX-ERROR-TIME
References: File System Interface (pp409-427)
Category: CLARIFICATION
Edit history: 07-Jul-88, Version 1 by Pitman
Status: For Internal Discussion
Problem Description:
There exist conceivable pathnames for which there is no valid mapping in a
particular implementation. CLtL is not clear about the time at which this
error might be detected.
For example, on file systems which constrain pathname-types to be three
letters or fewer, the type "LISP" is not valid. The question arises: when
is this error detected?
In some implementations, the error might be detected while forming the
pathname. That is, (MAKE-PATHNAME :TYPE "LISP") signals an error.
In some implementations, the error might be detected while forming the
namestring. That is, (MAKE-PATHNAME :TYPE "LISP") succeeds, but
(NAMESTRING (MAKE-PATHNAME :TYPE "LISP")) signals an error.
In some implementations, validity checking might be done only by the host
operating system, so Lisp does not detect the error unless the operating
system complains. For example, (MAKE-PATHNAME :TYPE "LISP") succeeds,
and even (NAMESTRING (MAKE-PATHNAME :TYPE "LISP")) constructs a plausible
looking pathname, but (OPEN (NAMESTRING (MAKE-PATHNAME :TYPE "LISP"))) fails.
In some implementations, Lisp might make `friendly' corrections to the
pathname in order to form a namestring. For example,
(MAKE-PATHNAME :TYPE "LISP") might succeed, but
(NAMESTRING (MAKE-PATHNAME :TYPE "LISP")) might produce a namestring with
an extension such as ".LIS" or ".LSP".
Similar issues might come up in file systems which don't allow wildcard
pathnames. Is :WILD allowed in a name or type slot and then disallowed
upon coercion to a pathname, or is :WILD complained about "up front"?
This phenomenon is a barrier to portability because if a program is
debugged in an implementation that does, for example, NAMESTRING-time
error checking, the programmer may be lulled into an expectation that
it is acceptable to construct and manipulate invalid pathnames as long
as the problem is caught before an attempt to call NAMESTRING is
attempted. On the other hand, another programmer may debug his code in
a Lisp which does early error checking of syntax and may assume that
he is home free if the pathname gets constructed correctly.
Proposal (PATHNAME-SYNTAX-ERROR-TIME:PATHNAME-CREATION):
Clarify that operations such as MAKE-PATHNAME and MERGE-PATHNMES which
construct new pathnames do plausibility checking of their arguments
and signal an error rather than construct a pathname for which NAMESTRING
would not produce a valid pathname.
Rationale:
This would identify clearly to the programmer where he should expect an
error to be signalled for a pathname.
This would mean that fully constructed pathnames could reliably
be converted to namestrings.
Cost to Implementors:
Some implementors, especially those which rely on the operating system
to be the sole authority on pathname syntax, might have to introduce
some new syntax-checking facilities.
Implementations where this error checking is done later would have to be
changed both to do it earlier, and to not make the unwarranted assumption
that pathnames with no valid namestring representation are constructable.
Cost to Users:
The ability to represent non-viable pathnames for the purpose of merging
would be lost. This feature was not portably available, but was available
in some operating systems.
Some code which expected an error, but expected it at a different time
would have to be changed.
Proposal (PATHNAME-SYNTAX-ERROR-TIME:NAMESTRING-COERCION):
Clarify that it was valid to create a pathname which could not be
converted to a namestring. Require NAMESTRING (and related functions,
such as ENOUGH-NAMESTRING or any internal functions that might be used
in place of NAMESTRING by functions like OPEN and PROBE-FILE) to signal
an error for pathnames which do not represent valid filenames in the
designated file system.
Rationale:
This would identify clearly to the programmer where he should expect an
error to be signalled for a pathname.
This would allow the construction of pathnames for the sole purpose of
merging without causing what might seem to some as gratuitous errors.
Cost to Implementors:
Implementors who rely on the operating system to be the sole authority
on pathname syntax, might have to introduce some new syntax-checking
facilities.
Implementations where this error checking is done earlier would have to
be changed both to do it later, and to not make the unwarranted
assumption that any pathname has a valid namestring representation.
Cost to Users:
Early error checking of faulty pathnames would be lost.
Some code which expected an error, but expected it at a different time
would have to be changed.
Benefits:
Macsyma, for example, has encountered a need for "hostless" pathnames
(in merging). The concept makes no sense if every pathname must have
a namestring, because a pathname with no host cannot have a namestring.
However, if it's NAMESTRING's responsibility to signal an error, then
hostless pathnames are still useful for merging. Consider:
(MERGE-PATHNAMES (MAKE-PATHNAME :NAME "FRED") MARY)
This will override both the NAME and the HOST field of MARY because you
must currently have a host in every pathname. But if MAKE-PATHNAME did
not force the host, or if one could explicitly say :HOST NIL, then
such pathnames would be considerably more useful for merging.
Proposal (PATHNAME-SYNTAX-ERROR-TIME:EXPLICITLY-VAGUE):
Clarify that we were unable to reach agreement on this issue and that
the time at which this error detection occurs is not well-specified.
Advise the editorial group to warn users clearly about this known source
of program portability problems.
Rationale:
This implements the status quo.
Cost to Implementors:
None.
Cost to Users:
No existing code must be modified, but there is an ongoing cost
associated with providing error checking at multiple points in a
program because implementations disagree as to where an error
might be signalled. In some cases, the effects of having to handle
this in multiple places may cause unpleasant modularity violations.
Test Case:
See problem description.
Current Practice:
Symbolics Genera signals an error at pathname construction time if a
pathname will be invalid. Once a pathname is successfully constructed,
it can generally be assumed that NAMESTRING will always succeed.
Aesthetics:
Making this more well-defined would cause a definite aesthetic
improvement to some programs.
Discussion:
Pitman prefers PATHNAME-SYNTAX-ERROR-TIME:NAMESTRING-COERCION but
believes that anything is an improvement over ...:EXPLICITLY-VAGUE.
CL pathname functions were not adequate for use in Macsyma because
they did not adequately represent to-be-merged-only pathnames (a
feature used very extensively in Macsyma), because errors could be
signalled at radically different times. To get around this, Pitman
had to create a data structure in Macsyma called an MPATHNAME which
was only trivially different than a PATHNAME but which made it
possible to deal portably with this issue of when errors occurred
and what kinds of errors occured. Unfortunately, since none of the
CL functions worked on MPATHNAMEs, a whole series of functions,
also only trivially different, had to be created: MAKE-MPATHNAME,
MNAMESTRING, MERGE-MPATHNAMES, MPATHNAME-NAME, MPATHNAME-TYPE,
MOPEN, WITH-MOPEN-FILE, etc.
------
Summary of CL-Cleanup discussion:
Most of the mail was endorsements for option PATHNAME-CREATION.
Sandra brought up a tangential issue about truenames that eventually
became a separate issue.
I think I'm the only person pushing NAMESTRING-COERCION. I strongly
believe it is the right thing, and that PATHNAME-CREATION is suboptimal,
based on problems that have struck me with existing CL pathname system.
However, even PATHNAME-CREATION would be an improvement from a
portability standpoint and I am probably not going to push it because
there are compatibility issues on the side of PATHNAME-CREATION (many
implementations do this already), and because there are more important
issues for us to spend time on at the meeting.
[Please try to come prepared to vote yes on one or both of
PATHNAME-CREATION or NAMESTRING-COERCION so we don't have to fall back
on EXPLICITLY-VAGUE, which is a total loss for program portability.
-kmp]
∂24-Mar-89 0824 X3J13-mailer Re: 20 March cs proposal
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Mar 89 08:24:29 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA02507; Fri, 24 Mar 89 09:24:27 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA13370; Fri, 24 Mar 89 09:24:24 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903241624.AA13370@defun.utah.edu>
Date: Fri, 24 Mar 89 09:24:23 MST
Subject: Re: 20 March cs proposal
To: Thom Linden <baggins@IBM.com>
Cc: Common Lisp mailing <x3j13@sail.stanford.edu>
In-Reply-To: Thom Linden <baggins@IBM.com>, Wed, 22 Mar 89 15:01:01 PST
The organization of this document is much improved -- I found the
presentation to be much more coherent (although some of the proposals
still seem to be grouped in the wrong place) and was able to make some
connections between the various parts that I hadn't been able to make
before. However, there also seemed to be a few things that got lost
between the last version and this one.
Page 4: I find the use of the word "control" to describe non-graphic
characters confusing (it has too many other connotations). CLtL used
"non-graphic"; let's stick with that term.
Page 6: Something that appears to have gotten lost from the previous
version is removing the statement from CLtL that characters with
non-zero bits and font are not STANDARD-CHARs. As I understand your
proposals, you want STANDARD-CHARs to be STANDARD-CHARs regardless of
whether or not they have any attributes associated with them, right?
Page 7: "Redefine STRING-CHAR". Why not just remove/deprecate it
entirely? STRING-CHAR used to identify what characters could be
stored in a string; the new set of proposals has defined STRING so
that any character can be stored in one. Also, it seems like this
item doesn't really belong in this particular proposal (since it has
little to do with removing bits and fonts).
Page 12: "it is an error to insert an extended character into a base
string" => "the consequences are undefined"?
Page 14, section 2.4: Unless and until there is an ISO standard for
character registries, I think it would be silly to include the
proposals in this section in the standard. For example, implementors
would have to arbitrarily define their own repertoires and labels for
the characters they support, which would almost certainly be
incompatible with any standard that is eventually adopted as well as
with the repertoires defined by other implementations. This would
make it impossible to use the functions proposed in this section
portably.
Page 18: In proposal 2.5.1, what is the interpretation of the "name"
argument? Must it follow the same rules as described for the
:EXTERNAL-CODE option to OPEN below? Is a list valid? How about
the keyword :DEFAULT?
Page 18: The material in proposals 2.5.1 and 2.5.2 can not be used
portably, for two reasons. First, there are no standard names for
coded character sets being proposed here. Second, even if we
standardized names, implementations are not being required to support
any particular coded character sets. Therefore I believe this
functionality has no place in the standard. I wouldn't have any
objection to simply stating that OPEN can be extended to accept
additional keyword arguments that are treated in an
implementation-specific manner, or even saying that it takes an
:EXTERNAL-CODE keyword that is treated in an implementation-specific
manner, but let's at least be honest about the nonportability and
not mislead users into thinking these things are more portable than
they really are.
Page 19, Proposal 2.5.4: Given the discussion on page 11, it seems
like the right default :ELEMENT-TYPE is BASE-CHARACTER. But I won't
quibble about it.
Page 20, STRING-ENCODED-LENGTH: In the previous version of the
writeup, there was some verbiage (on page 14) that said that this
function takes a string or character object as its required argument.
This has been lost. Is this function now intended to take *any*
object as an argument and determine how much room its printed
representation will take?
I still think this function is useless as currently defined.
"Implementation defined units" is just too vague. I could probably be
convinced to vote for adding such a function if it were tied to the
FILE-POSITION function -- for example, define STRING-ENCODED-LENGTH as
the difference between what (FILE-POSITION output-stream) would be
after writing the string and its current value. It might also be
more appropriate to name it FILE-STRING-LENGTH or something like that
and rearrange the arguments to make it parallel FILE-POSITION and
FILE-LENGTH.
Page 20, Proposal 2.6.2: Why prohibit control (non-graphic) characters
from appearing in a symbol's print name? The context in which the
sentence this replaces appears has to do with how the reader deals
with the case of symbol names, not with restricting what characters
are valid in the print name.
Page 20, Proposal 2.6.4: "It is an error" => "the consequences are
undefined"?
-------
∂24-Mar-89 1457 X3J13-mailer **DRAFT** Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Mar 89 14:57:39 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 564943; Fri 24-Mar-89 17:57:27 EST
Date: Fri, 24 Mar 89 17:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4)
To: X3J13@SAIL.STANFORD.EDU
In-Reply-To: <890323155755.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-ID: <19890324225719.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Due to a lack of coordination on our part, both Kent and I sent
mailings labelled Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4).
The two mailings were quite different. Kent agrees that the one
he sent should be ignored and the one I sent on Wednesday is the
one you're supposed to read. Sorry about that.
∂25-Mar-89 2231 X3J13-mailer **DRAFT** Issue: READ-CASE-SENSITIVITY (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Mar 89 22:31:39 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 565470; Sun 26-Mar-89 01:31:28 EST
Date: Sun, 26 Mar 89 01:30 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: READ-CASE-SENSITIVITY (Version 2)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890326013058.8.KMP@BOBOLINK.SCRC.Symbolics.COM>
>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<
This is just for the reference of anyone still reading mail this close
to the meeting, so that you will have seen it in case it (or some further
revision) comes up at the meeting. If you have any comments, just bring
them to the meeting. Thanks. -kmp
-----
Issue: READ-CASE-SENSITIVITY
Forum: Cleanup
References: CLtL p 334 ff: What the Read Function Accepts,
especially p 337, step 8, point 1.
CLtL p 360 ff: The Readtable
COPY-READTABLE (CLtL, p 361)
*PRINT-CASE* (CLtL, p 372)
Category: ADDITION/CHANGE
Edit history: Version 1, 15-Feb-89, by Dalton
Version 2, 23-Mar-89, by Dalton,
(completely new proposal after comments from
Pitman, Gray, Masinter, and R.Tobin@uk.ac.ed)
Problem Description:
The Common Lisp reader always converts unescaped constituent
characters to upper case. (See CLtL, p 337, step 8, point 1.)
This behavior is not always desirable.
1. Lisp applications often use the Lisp reader to read their data.
This is often significantly easier than writing input routines
from scratch, especially if the input can be structured as lists.
However, certain applications want to make use of case distinctions,
and Common Lisp makes this unreasonably difficult. (You must define
every letter as a read macro and have the macro function read the
rest of the symbol, or else you must write a reader from scratch.)
2. Some programming languages distinguish between upper and lower
case in identifiers, and useful conventions are often built around
such distinctions. For example, in C, constants are often written
in upper case and variables in lower. In Mesa(?) and Smalltalk(?),
a capital letter is used to indicate the beginning of a new word
in identifiers made up of several words. In Edinburgh Prolog,
variables begin with upper-case letters and constant symbols do
not. The case-insensitivity of the Common Lisp reader makes
it difficult to use conventions of this sort.
Proposal (READ-CASE-SENSITIVITY:READTABLE-KEYWORDS)
Define a new settable function, (READTABLE-CASE <readtable>) to
control the reader's interpretation of case. The following values
may be given:
:UPCASE -- convert unescaped characters to upper-case, as now.
:DOWNCASE -- convert unescaped characters to lower-case.
:PRESERVE -- don't convert, leaving lower-case letters in lower
case and upper-case characters in upper case.
:INVERT -- convert lower-case to upper and upper-case to lower.
COPY-READTABLE copies the setting of READTABLE-CASE. The value of
READTABLE-CASE for the standard readtable is :UPCASE.
The READTABLE-CASE of a readtable also has significance when
printing. The case in which letters are printed is determined as
follows:
When READ-CASE is :UPCASE, upper-case letters are printed in the
case specified by *PRINT-CASE*.
When READ-CASE is :DOWNCASE, lower-case letters are printed in
the case specified by *PRINT-CASE*.
When READ-CASE is :PRESERVE, letters are printed in their own
case.
When READ-CASE is :INVERT, the case of all letters is inverted.
(The behavior when *PRINT-CASE* is :CAPITALIZE is like :UPCASE for
the first character and :DOWNCASE for the rest.)
The rules for escaping letters are also affected by the READTABLE-CASE.
If *PRINT-ESCAPE* is true, letters are escaped as follows:
When READ-CASE is :UPCASE, all lower-case letters must be escaped.
When READ-CASE is :DOWNCASE, all upper-case letters must be escaped.
Otherwise, no letters need be escaped.
Proposal (READ-CASE-SENSITIVITY:READTABLE-FUNCTION)
Define a new settable function (READTABLE-CHARACTER-TRANSLATION
<readtable>) to control the reader's interpretation of unescaped
constituent characters. The value may be any function of type
(FUNCTION (CHARACTER) CHARACTER). Where the reader now converts
such characters to upper case it should instead call the function
that is the value of READTABLE-CHARACTER-TRANSLATION for the current
readtable. (See CLtL, page 337, step 8, point 1.)
COPY-READTABLE copies the setting of READTABLE-CHARACTER-TRANSLATION.
The value for the standard readtable is CHAR-UPCASE.
The READTABLE-CHARACTER-TRANSLATION of a readtable also has
significance when printing. The reader recognizes certain functions
which control the reader's interpretation of case and alters its
behavior accordingly. This behavior is given by the following
correspondence between functions and the keywords described above.
[This is just to avoid repeating a lot of text.]
function keyword
CHAR-UPCASE :UPCASE
CHAR-DOWNCASE :DOWNCASE
IDENTITY :PRESERVE
CHAR-INVERT-CASE :INVERT
The function can be given either as a symbol or as one of the values
#'CHAR-UPCASE, #'CHAR-DOWNCASE, #'IDENTITY, #'CHAR-INVERT-CASE.
If the READTABLE-CHARACTER-TRANSLATION is not one of the functions
listed above, letters are always printed in their own case (in
particular, *PRINT-CASE* has no effect), and all characters in
symbol names are escaped if *PRINT-ESCAPE* is true.
Define a new function CHAR-INVERT-CASE of type (FUNCTION (CHARACTER)
CHARACTER) analogous to CHAR-UPCASE and CHAR-DOWNCASE. It attempts
to convert its argument to upper-case if the argument is lower-case
and to lower-case if the argument is upper-case.
Rationale:
There are a number of different ways to achieve case-sensitivity.
These proposals are fairly simple but provide all of the
functionality that one could reasonably expect.
By using a property of the readtable, we avoid introducing a new
special variable. Any code that wishes to control all of the
reader's parameters already takes *READTABLE* into account. A new
special variable would require such code to change.
:DOWNCASE is included for symmetry with :UPCASE. :INVERT is
included so that case conventions could be used in Common Lisp code
without requiring that the names symbols in the "LISP" package be
written in upper case. (Opinions vary as to whether is is advisable
to use such conventions, but this proposal leaves that choice to the
user.)
In order to avoid complex interactions between the case setting of
the readtable and *PRINT-CASE*, this proposal specifies a
significance for *PRINT-CASE* only when the case setting is :UPCASE
or :DOWNCASE. The meaning of *PRINT-CASE* when the readtable
setting is :DOWNCASE was chosen for its simplicity and for symmetry
with :UPCASE while still being useful.
Test Case:
;; keyword version
(let ((rt (copy-readtable nil)))
(mapcar
#'(lambda (case)
(setf (readtable-case rt) case)
(read-from-string "Zebra"))
'(:upcase :downcase :preserve :invert)))
=> (ZEBRA |zebra| |Zebra| |zEBRA|) ;as printed with the standard
;readtable and *print-case* :upcase
Current Practice:
While there may not be any current implementation that supports
exactly this proposal, several implementations provide some means
for changing case sensitivity.
Franz Inc's ExCL has a function, EXCL:SET-CASE-MODE, that sets both
the "preferred case" (the case of character in the print names of
standard symbols such as CAR) and whether or not the reader is case-
sensitive.
In Symbolics Common Lisp, the function SET-CHARACTER-TRANSLATION
can be used to make the translation of a letter be that same letter,
thus achieving case-sensitivity.
Xerox Medley has a function for setting a readtable flag that
determines case sensitivity.
Cost to Implementors:
Fairly small. The reader will be slightly slower and readtables
will be slightly more complex.
Cost to Users:
Slight. Programmers must already take into account the possibility
that *READTABLE* will be a non-standard readtable. Case-sensitivity
is no worse than character macros in this respect.
Cost of Non-Adoption:
Applications that want to read mixed-case expressions will not
be able to use the Common Lisp reader to do so (except, perhaps,
by tortuous use of read macros).
Programming styles that rely on case distinctions (without escape
characters) will be effectively impossible in Common Lisp.
Benefits:
Applications will be able to read mixed-case expressions.
Programmers will be able to make use of case distinctions.
Aesthetics:
For the proposals:
The language will have greater symmetry, because it will be
possible to control the treatment of case on both input and output
instead of only on output (as is now the case).
The language will look less old-fashioned.
Against the proposals:
It is, perhaps, inconsistent to control case-sensitivity by a
readtable operation when other aspects of the reader, such as the
input base and the default float format (not to mention the
package), are controlled by special variables. However, it can be
argued that character-level syntax is determined chiefly by the
readtable. Case-sensitivity can be seen as analogous to character
macros in this respect.
Keywords vs function
The keyword proposal is somewhat simpler and avoids raising the
possibility of character translation that applies in general and
not just for unescaped constituents.
The function proposal is perhaps more elegant.
Discussion:
Dalton supports both proposals but slightly prefers READTABLE-CASE.
Version 1 of the proposal suggested a new global variable rather
than a property of the readtable. Pitman was strongly opposed to
that proposal and gave convincing arguments that it should be
dropped. Gray suggested that the readtable property should be a
function.
∂25-Mar-89 2239 X3J13-mailer **DRAFT** Issue: ERROR-CHECKING-IN-NUMBERS-CHAPTER (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Mar 89 22:38:54 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 565475; Sun 26-Mar-89 01:38:41 EST
Date: Sun, 26 Mar 89 01:38 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: ERROR-CHECKING-IN-NUMBERS-CHAPTER (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890326013810.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<
It's too late for any discussion, but this is just for the information
of anyone still tracking mail at this late date. If you have comments,
just bring them to the meeting. Thanks.
-kmp
-----
Issue: ERROR-CHECKING-IN-NUMBERS-CHAPTER
Forum: Cleanup
References: Numbers (pp193-232),
S:>kmp>cl>conditions>revision-18-notes.text.34
(formerly S:>kmp>cl-conditions.text.34),
Category: CHANGE
Edit history: 06-Mar-89, Version 1 by Pitman
Status: For Internal Discussion
Problem Description:
In many cases, CLtL specifies ``is an error'' situations for functions
in places that programmers would prefer to see an error signalled.
Reliably signalling an error accomplishes two things...
- It eases the development process by making it easier to notice errors
in a timely fashion.
- It makes it easier for code to reliably handle errors at runtime,
leading to greater robustness in delivered applications.
Proposal (ERROR-CHECKING-IN-NUMBERS-CHAPTER:SCARECROW): - a straw man...
ABS should signal TYPE-ERROR if its argument is not type NUMBER.
ACOS should signal TYPE-ERROR if its argument is not type NUMBER.
ACOS might signal ARITHMETIC-ERROR.
ACOSH should signal TYPE-ERROR if its argument is not type NUMBER.
ACOSH might signal ARITHMETIC-ERROR.
ASH should signal TYPE-ERROR if either argument is not type INTEGER.
ASH might signal ARITHMETIC-ERROR.
ASIN should signal TYPE-ERROR if its argument is not type NUMBER.
ASIN might signal ARITHMETIC-ERROR.
ASINH should signal TYPE-ERROR if its argument is not type NUMBER.
ASINH might signal ARITHMETIC-ERROR.
ATAN should signal TYPE-ERROR if exactly one argument is given and that
argument is not type NUMBER.
ATAN should signal TYPE-ERROR if exactly two arguments are given and
either argument is not type (AND NUMBER (NOT COMPLEX)).
ATAN might signal ARITHMETIC-ERROR.
ATANH should signal TYPE-ERROR if its argument is not type NUMBER.
ATANH might signal ARITHMETIC-ERROR.
BOOLE should signal TYPE-ERROR if its first argument is not type
(MEMBER #.BOOLE-CLR #.BOOLE-SET #.BOOLE-1 #.BOOLE-2
#.BOOLE-C1 #.BOOLE-C2 #.BOOLE-AND #.BOOLE-IOR
#.BOOLE-XOR #.BOOLE-EQV #.BOOLE-NAND #.BOOLE-NOR
#.BOOLE-ANDC1 #.BOOLE-ANDC2 #.BOOLE-ORC1 #.BOOLE-ORC2)
BOOLE should signal TYPE-ERROR if either its second or third
argument is not type INTEGER.
BYTE should signal TYPE-ERROR if either argument is not type INTEGER.
BYTE-POSITION might signal TYPE-ERROR if its argument is not a byte
specifier (something that was returned by the BYTE
function). Note that byte specifiers are not required
to be disjoint from other types, so this error checking
is only heuristic.
BYTE-SIZE might signal TYPE-ERROR if its argument is not a byte
specifier (something that was returned by the BYTE
function). Note that byte specifiers are not required
to be disjoint from other types, so this error checking
is only heuristic.
CEILING should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
CEILING should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
CEILING should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
CEILING might signal ARITHMETIC-ERROR.
COMPLEX should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
COMPLEX should signal TYPE-ERROR if its second argument is provided
but is not type (AND NUMBER (NOT COMPLEX)).
CONJUGATE should signal TYPE-ERROR if its argument is not type NUMBER.
CIS should signal TYPE-ERROR if its argument is not type
(AND NUMBERP (NOT COMPLEX)).
CIS might signal ARITHMETIC-ERROR.
COS should signal TYPE-ERROR if its argument is not type NUMBER.
COS might signal ARITHMETIC-ERROR.
COSH should signal TYPE-ERROR if its argument is not type NUMBER.
COSH might signal ARITHMETIC-ERROR.
DECF might signal SYNTAX-ERROR at semantic processing time.
DECF should signal TYPE-ERROR at runtime if the variable to be
incremented does not have a value of type NUMBER.
DECF might signal ARITHMETIC-ERROR at runtime.
DECODE-FLOAT should signal TYPE-ERROR if its argument is not type FLOAT.
DENOMINATOR should signal TYPE-ERROR if its argument is not type RATIONAL.
DEPOSIT-FIELD should signal TYPE-ERROR if its first argument is not type
INTEGER.
DEPOSIT-FIELD might signal TYPE-ERROR if its second argument is not a
bytespec (something returned by BYTE). Note that byte
specifiers are not required to be disjoint from other types,
so this error checking is only heuristic.
DEPOSIT-FIELD should signal TYPE-ERROR if its third argument is not type
INTEGER.
DPB should signal TYPE-ERROR if its first argument is not type INTEGER.
DPB might signal TYPE-ERROR if its second argument is not a bytespec
(something returned by BYTE). Note that byte specifiers are not
required to be disjoint from other types, so this error checking
is only heuristic.
DPB should signal TYPE-ERROR if its third argument is not type INTEGER.
EVENP should signal TYPE-ERROR if its argument is not type INTEGER.
FCEILING should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FCEILING should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FCEILING should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FCEILING might signal ARITHMETIC-ERROR.
FFLOOR should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FFLOOR should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FFLOOR should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FFLOOR might signal ARITHMETIC-ERROR.
FLOOR should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FLOOR should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FLOOR should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FLOOR might signal ARITHMETIC-ERROR.
FROUND should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FROUND should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FROUND should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FROUND might signal ARITHMETIC-ERROR.
FTRUNCATE should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FTRUNCATE should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FTRUNCATE should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FTRUNCATE might signal ARITHMETIC-ERROR.
GCD should signal TYPE-ERROR if any argument is not type INTEGER.
GCD might signal ARITHMETIC-ERROR.
EXP should signal TYPE-ERROR if its argument is not type NUMBER.
EXP might signal ARITHMETIC-ERROR.
EXPT should signal TYPE-ERROR if either argument is not type NUMBER.
EXPT might signal ARITHMETIC-ERROR. e.g., (EXPT 0 0.0)
FLOAT should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FLOAT should signal TYPE-ERROR if its second argument is supplied
but is not type FLOAT.
FLOAT might signal ARITHMETIC-ERROR.
FLOAT-DIGITS should signal TYPE-ERROR if its argument is not type FLOAT.
FLOAT-PRECISION should signal TYPE-ERROR if its argument is not type FLOAT.
FLOAT-RADIX should signal TYPE-ERROR if its argument is not type FLOAT.
FLOAT-SIGN should signal TYPE-ERROR if its first argument is not type
FLOAT.
FLOAT-SIGN should signal TYPE-ERROR if its second argument is supplied
but is not type FLOAT.
INCF might signal SYNTAX-ERROR at semantic processing time.
INCF should signal TYPE-ERROR at runtime if the variable to be
incremented does not have a value of type NUMBER.
INCF might signal ARITHMETIC-ERROR at runtime.
INTEGER-DECODE-FLOAT should signal TYPE-ERROR if its argument is not
type FLOAT.
INTEGER-LENGTH should signal TYPE-ERROR if its argument is not type INTEGER.
IMAGPART should signal TYPE-ERROR if its argument is not type NUMBER.
ISQRT should signal TYPE-ERROR if its argument is not type (INTEGER 0).
ISQRT might signal ARITHMETIC-ERROR.
LCM should signal TYPE-ERROR if any argument is not type INTEGER.
LCM might signal ARITHMETIC-ERROR.
LDB might signal TYPE-ERROR if its first argument is not a bytespec
(something returned by BYTE). Note that byte specifiers are not
required to be disjoint from other types, so this error checking
is only heuristic.
LDB should signal TYPE-ERROR if its second argument is not type INTEGER.
LDB-TEST might signal TYPE-ERROR if its first argument is not a bytespec
(something returned by BYTE). Note that byte specifiers are not
required to be disjoint from other types, so this error checking
is only heuristic.
LDB-TEST should signal TYPE-ERROR if its second argument is not type INTEGER.
LOG should signal TYPE-ERROR if either argument is not type NUMBER.
LOG might signal ARITHMETIC-ERROR.
LOGAND should signal TYPE-ERROR if any argument is not type INTEGER.
LOGANDC1 should signal TYPE-ERROR if either argument is not type INTEGER.
LOGANDC2 should signal TYPE-ERROR if either argument is not type INTEGER.
LOGBITP should signal TYPE-ERROR if its first argument is not type
(INTEGER 0).
LOGBITP should signal TYPE-ERROR if its second argument is not type
INTEGER.
LOGCOUNT should signal TYPE-ERROR error if its argument is not type INTEGER.
LOGEQV should signal TYPE-ERROR if any argument is not type INTEGER.
LOGIOR should signal TYPE-ERROR if any argument is not type INTEGER.
LOGNAND should signal TYPE-ERROR if either argument is not type INTEGER.
LOGNOR should signal TYPE-ERROR if either argument is not type INTEGER.
LOGNOT should signal TYPE-ERROR error if its argument is not type INTEGER.
LOGORC1 should signal TYPE-ERROR if either argument is not type INTEGER.
LOGORC2 should signal TYPE-ERROR if either argument is not type INTEGER.
LOGTEST should signal TYPE-ERROR if either argument is not type INTEGER.
LOGXOR should signal TYPE-ERROR if any argument is not type INTEGER.
MAKE-RANDOM-STATE should signal TYPE-ERROR if an argument is supplied
but is not type (OR (MEMBER NIL T) RANDOM-STATE).
MASK-FIELD might signal TYPE-ERROR if its first argument is not a bytespec
(something returned by BYTE). Note that byte specifiers are not
required to be disjoint from other types, so this error checking
is only heuristic.
MASK-FIELD should signal TYPE-ERROR if its second argument is not type
INTEGER.
MAX should signal TYPE-ERROR if any argument is not type
(AND NUMBERP (NOT COMPLEX)).
MAX might signal ARITHMETIC-ERROR.
MIN should signal TYPE-ERROR if any argument is not type
(AND NUMBERP (NOT COMPLEX)).
MIN might signal ARITHMETIC-ERROR.
MINUSP should signal TYPE-ERROR if its argument is not type
(AND NUMBER (NOT COMPLEX)).
MOD should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
MOD should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
MOD should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
MOD might signal ARITHMETIC-ERROR.
NUMERATOR should signal TYPE-ERROR if its argument is not type RATIONAL.
ODDP should signal TYPE-ERROR if its argument is not type INTEGER.
PHASE should signal TYPE-ERROR if its argument is not type NUMBER.
PHASE might signal ARITHMETIC-ERROR.
PLUSP should signal TYPE-ERROR if its argument is not type
(AND NUMBER (NOT COMPLEX)).
RANDOM should signal TYPE-ERROR if its first argument is not
type (INTEGER 1).
RANDOM should signal TYPE-ERROR if its second argument is supplied
but is not type RANDOM-STATE.
RANDOM-STATE-P will never signal an error.
RATIONAL should signal TYPE-ERROR if its argument is not type
(AND NUMBER (NOT COMPLEX)).
RATIONAL might signal ARITHMETIC-ERROR.
RATIONALIZE should signal TYPE-ERROR if its argument is not type
(AND NUMBER (NOT COMPLEX)).
RATIONALIZE might signal ARITHMETIC-ERROR.
REALPART should signal TYPE-ERROR if its argument is not type NUMBER.
REM should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
REM should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
REM should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
REM might signal ARITHMETIC-ERROR.
ROUND should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
ROUND should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
ROUND should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
ROUND might signal ARITHMETIC-ERROR.
SCALE-FLOAT should signal TYPE-ERROR if its first argument is not
type FLOAT.
SCALE-FLOAT should signal TYPE-ERROR if its second argument is not
type INTEGER.
SIGNUM should signal TYPE-ERROR if its argument is not type NUMBER.
SIN should signal TYPE-ERROR if its argument is not type NUMBER.
SIN might signal ARITHMETIC-ERROR.
SINH should signal TYPE-ERROR if its argument is not type NUMBER.
SINH might signal ARITHMETIC-ERROR.
SQRT should signal TYPE-ERROR if its argument is not type NUMBER.
SQRT might signal ARITHMETIC-ERROR.
TAN should signal TYPE-ERROR if its argument is not type NUMBER.
TAN might signal ARITHMETIC-ERROR.
TANH should signal TYPE-ERROR if its argument is not type NUMBER.
TANH might signal ARITHMETIC-ERROR.
TRUNCATE should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
TRUNCATE should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
TRUNCATE should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
TRUNCATE might signal ARITHMETIC-ERROR.
ZEROP should signal TYPE-ERROR if its argument is not type NUMBER.
* should signal TYPE-ERROR if any argument is not type NUMBER.
* might signal ARITHMETIC-ERROR.
+ should signal TYPE-ERROR if any argument is not type NUMBER.
+ might signal ARITHMETIC-ERROR.
- should signal TYPE-ERROR if any argument is not type NUMBER.
- might signal ARITHMETIC-ERROR.
/ should signal TYPE-ERROR if any argument is not type NUMBER.
/ should signal DIVISION-BY-ZERO if any divisor argument is zero.
/ might signal ARITHMETIC-ERROR.
/= should signal type-error if any argument is not type NUMBER.
/= might signal ARITHMETIC-ERROR.
1+ should signal TYPE-ERROR if any argument is not type NUMBER.
1+ might signal ARITHMETIC-ERROR.
1- should signal TYPE-ERROR if any argument is not type NUMBER.
1- might signal ARITHMETIC-ERROR.
< should signal TYPE-ERROR if any argument is not type
(AND NUMBER (NOT COMPLEX)).
< might signal ARITHMETIC-ERROR.
<= should signal TYPE-ERROR if any argument is not type
(AND NUMBER (NOT COMPLEX)).
<= might signal ARITHMETIC-ERROR.
= should signal TYPE-ERROR if any argument is not type NUMBER.
= might signal ARITHMETIC-ERROR.
> should signal TYPE-ERROR if any argument is not type
(AND NUMBER (NOT COMPLEX)).
> might signal ARITHMETIC-ERROR.
>= should signal TYPE-ERROR if any argument is not type
(AND NUMBER (NOT COMPLEX)).
>= might signal ARITHMETIC-ERROR.
Rationale:
This addresses the development and delivery concerns mentioned in the
Problem Description.
Current Practice:
Most implementations probably do not reliably signal the indicated
errors in safe code.
Cost to Implementors:
In implementations not providing the indicated error checking,
considerable work might need to be done.
The alternative is to identify the implementation as an "unsafe" subset.
However, while it is a "subset" in the sense that code that was developed
in it will run in the superset, it is important to understand that such
implementations are not simply "places you can run code that's been
thoroughly debugged in the full language" since such debugged code may
still depend on the reliable detection and handling of certain kinds of
errors.
Cost to Users:
Technically none. These are supposedly already all `is an error'
cases that people can't depend on.
Some users might be relying on an implementation not to signal a particular
error in compiled code. Such code is already not portable, however.
In some cases, where an implementation adds error checking that they
consider unnecessary, the user will need to add some OPTIMIZE proclamations.
Some users will see this as a bug fix.
Cost of Non-Adoption:
The error handling facilities will be a lot less useful.
Code that uses error handling will not port well.
Benefits:
Better development environments. More robust delivered applications.
Aesthetics:
Hopefully improved.
Discussion:
Pitman getting this level of detail is a good idea. He's ammenable to
specific changes if they improve the overall level of receptiveness to
the proposal.
Notes about how to proceed on this issue
(to be removed prior to final vote):
- Is anyone uncomfortable about the name ARITHMETIC-ERROR?
If so, can someone mathematically inclined suggest a better name?
`MATH-ERROR' or `NUMBER-ERROR' come to mind.
- In some of the cases of "might signal", it might be the case that
no signal should ever occur. Someone who's actually implemented these
functions might want to suggest that in some cases we can remove
this verbiage, or give examples of the circumstances under which the
condition might be signalled?
∂26-Mar-89 2005 X3J13-mailer **DRAFT** Issue: PRINT-CASE-PRINT-ESCAPE-INTERACTION (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Mar 89 20:05:29 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 565792; Sun 26-Mar-89 23:05:21 EST
Date: Sun, 26 Mar 89 23:04 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PRINT-CASE-PRINT-ESCAPE-INTERACTION (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890326230447.7.KMP@BOBOLINK.SCRC.Symbolics.COM>
>>> DO -NOT- REPLY TO THIS ISSUE <<<
No one is reading mail at this point anyway. (I don't even seriously
believe anyone will read -this- before the meeting, but I wanted it to
be on file just in case.) Just ponder it and bring any comments you
have to the meeting.
See additional notes at end.
-----
Issue: PRINT-CASE-PRINT-ESCAPE-INTERACTION
Forum: Cleanup
References: *PRINT-ESCAPE* (pp370-371), *PRINT-CASE* (pp372), WRITE
Category: CLARIFICATION
Edit history: 26-Jan-89, Version 1 by Pitman
Status: For Internal Discussion
Problem Description:
The wording on page 372 of CLtL uses fuzzy terms that make it hard
to tell if *PRINT-ESCAPE* interacts with *PRINT-CASE*.
Paragraph 1 of the description of *PRINT-CASE* says "This variable
controls the case (upper, lower, or mixed) in which to print any
uppercase characters in the names of symbols when vertical-bar
syntax is used."
Paragraph 2 begins with the seemingly unambiguous statement "Lowercase
characters in the internal print name are always printed in lowercase"
but then goes on to muddy the water by saying "and are preceded by
a single escape character or enclosed by multiple escape characters".
This escaping presumably only happens in *PRINT-ESCAPE* T mode, which
leads one to wonder if other parts of the *PRINT-ESCAPE* description are
implicitly controlled by *PRINT-ESCAPE* as well.
The function WRITE is affected by implication.
Proposal (PRINT-CASE-PRINT-ESCAPE-INTERACTION:LIKE-PRIN1):
Define that *PRINT-CASE* cases characters the same as PRIN1 would.
Proposal (PRINT-CASE-PRINT-ESCAPE-INTERACTION:LIKE-WRITE-STRING):
Define that *PRINT-CASE* has an effect only when *PRINT-ESCAPE* is T.
When *PRINT-CASE* is NIL, WRITE-STRING is used directly.
Proposal (PRINT-CASE-PRINT-ESCAPE-INTERACTION:VERTICAL-BAR-RULE-NO-UPCASE):
Define that *PRINT-CASE* has an effect at all times when *PRINT-ESCAPE*
is NIL. Define that *PRINT-CASE* also has an effect when *PRINT-ESCAPE*
is T unless inside an escape context (i.e., unless between vertical bars
or after a slash). Under no circumstance is any character which was
lowercase in the internal representation ever presented as uppercase
due to *PRINT-CASE*.
Proposal (PRINT-CASE-PRINT-ESCAPE-INTERACTION:VERTICAL-BAR-RULE-PERMIT-UPCASE):
Like VERTICAL-BAR-RULE-NO-UPCASE, but permit *PRINT-CASE* to upcase
lowercase characters in the *PRINT-ESCAPE* NIL case since preservation of
Lisp syntax is not important there.
Proposal (PRINT-CASE-PRINT-ESCAPE-INTERACTION:EXPLICITLY-VAGUE):
Specify that the effect of *PRINT-CASE* when *PRINT-ESCAPE* is NIL
is implementation-dependent.
Test Case:
(LET ((RESULT '()) (TABWIDTH 12))
(DOLIST (SYMBOL '(|x| |FoObAr| |fOo|))
(LET ((TAB -1))
(FORMAT T "~&")
(DOLIST (ESCAPE '(T NIL))
(DOLIST (CASE '(:UPCASE :DOWNCASE :CAPITALIZE))
(FORMAT T "~VT" (* (INCF TAB) TABWIDTH))
(WRITE SYMBOL :ESCAPE ESCAPE :CASE CASE))))))
For each of the following, two clusters of output is shown. The first is
how an implementation which leans heavily on vertical bars might work.
The second is how an implementation which leans heavily on slash might
work. In fact, other interpretations are possible (mixing slash and
vertical bar). These examples are not an exhaustive analysis of the
implications of each proposal.
Possible outputs under LIKE-PRIN1:
|x| |x| |x| x x x
|FoObAr| |FoObAr| |FoObAr| FoObAr FoObAr FoObAr
|fOo| |fOo| |fOo| fOo fOo fOo
\x \x \x x x x
F\oO\bA\r f\oo\ba\r F\oo\ba\r FoObAr foobar Foobar
\fO\o \fo\o \fo\o fOo foo foo
Possible output under LIKE-WRITE-STRING:
|x| |x| |x| x x x
|FoObAr| |FoObAr| |FoObAr| FoObAr FoObAr FoObAr
|fOo| |fOo| |fOo| fOo fOo fOo
\x \x \x x x x
F\oO\bA\r f\oo\ba\r F\oo\ba\r FoObAr FoObAr FoObAr
\fO\o \fo\o \fo\o fOo fOo fOo
Possible output under VERTICAL-BAR-RULE-NO-UPCASE:
|x| |x| |x| x x x
|FoObAr| |FoObAr| |FoObAr| FoObAr foobar Foobar
|fOo| |fOo| |fOo| fOo foo foo
\x \x \x x x x
F\oO\bA\r f\oo\ba\r F\oo\ba\r FoObAr foobar Foobar
\fO\o \fo\o \fo\o fOo foo foo
Possible output under VERTICAL-BAR-RULE-PERMIT-UPCASE:
|x| |x| |x| X x X
|FoObAr| |FoObAr| |FoObAr| FOOBAR foobar Foobar
|fOo| |fOo| |fOo| FOO foo Foo
\x \x \x X x X
F\oO\bA\r f\oo\ba\r F\oo\ba\r FOOBAR foobar Foobar
\fO\o \fO\o \fO\o FOO foo Foo
Rationale:
It's silly for implementations to vary on this point.
Current Practice:
A strict reading of CLtL suggests that probably VERTICAL-BAR-RULE-NO-UPCASE
is the most correct.
Symbolics Genera doesn't do any of these. It was trying to do
VERTICAL-BAR-NO-UPCASE, but it had a bug which was about to be fixed when
this issue was raised.
Cost to Implementors:
Probably trivial.
Cost to Users:
Negligible in most cases. Probably very few users depend on this.
Those who do depend on it probably do so because they think the
behavior doesn't vary and probably don't get the portable behavior they
expect.
Cost of Non-Adoption:
Gratuitous variation between implementations.
Benefits:
Cost of non-adoption is avoided.
Aesthetics:
Anything that makes the language tighter probably improves aesthetics.
Only VERTICAL-BAR-RULE-PERMIT-UPCASE and LIKE-WRITE-STRING have really
useful behaviors in the :ESCAPE NIL situation. Of these, perhaps only
VERTICAL-BAR-RULE-PERMIT-UPCASE is really visually pleasant.
Discussion:
Pitman doesn't think the particular choice is very important. He just
wants the issue to be resolved. His slight preference is for
VERTICAL-BAR-RULE-PERMIT-UPCASE, then LIKE-WRITE-STRING, then either
of LIKE-PRIN1 or VERTICAL-BAR-RULE-NO-UPCASE. He sees no reason to go
with EXPLICITLY-VAGUE unless we deadlock.
Michael Greenwald, who raised the issue at Symbolics, doesn't have
a preference either but believes that CLtL (perhaps unintentionally)
leans toward VERTICAL-BAR-RULE-NO-UPCASE.
-----
Additional Discussion from CL-Cleanup:
David Gray responds:
> Possible output under VERTICAL-BAR-RULE-NO-UPCASE:
>
> |x| |x| |x| x x x
> |FoObAr| |FoObAr| |FoObAr| FoObAr foobar Foobar
> |fOo| |fOo| |fOo| fOo foo foo
This is exactly what the Explorer does.
There are several options for this issue, but if you're looking for one
to focus on, VERTICAL-BAR-RULE-NO-UPCASE is probably the one we'll push
if this issue comes up for discussion since it is believed most compatible
with current practice.
-kmp
∂26-Mar-89 2146 CL-Characters-mailer Really about TYPEP failures
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by SAIL.Stanford.EDU with TCP; 26 Mar 89 21:46:40 PST
Received: from F.ILA.Dialnet.Symbolics.COM (DIAL|16174944833) by Riverside.SCRC.Symbolics.COM via DIAL with SMTP id 326013; 27 Mar 89 00:44:44 EST
Received: from CALVARY.ILA.Dialnet.Symbolics.COM by F.ILA.Dialnet.Symbolics.COM via CHAOS with CHAOS-MAIL id 12127; Mon 27-Mar-89 00:45:13 EST
Date: Mon, 27 Mar 89 00:45 EST
From: Dennis L. Doughty <doughty@FUJI.ILA.Dialnet.Symbolics.COM>
Subject: Really about TYPEP failures
To: David A. Moon <Moon@Riverside.SCRC.Symbolics.COM>
cc: Jon L White <jonl%lucid.com@Riverside.SCRC.Symbolics.Com>, Baggins%IBM.COM@Riverside.SCRC.Symbolics.Com,
CL-Characters%SAIL.STANFORD.EDU@Riverside.SCRC.Symbolics.Com, X3J13%SAIL.STANFORD.EDU@Riverside.SCRC.Symbolics.Com,
Common-Lisp-Implementors@Riverside.SCRC.Symbolics.Com, KMP@Riverside.SCRC.Symbolics.Com,
Palter@Riverside.SCRC.Symbolics.Com
In-Reply-To: <19890303033902.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890327054506.1.DOUGHTY@CALVARY.ILA.Dialnet.Symbolics.COM>
Date: Thu, 2 Mar 89 22:39 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Sat, 4 Feb 89 09:27 EST
From: Robert W. Kerns <RWK@FUJI.ILA.Dialnet.Symbolics.COM>
Legitimate operations on BASE-CHARACTER do not
produce characters in (AND CHARACTER (NOT BASE-CHARACTER)).
I'm not sure which programs written using symbols in the LISP package
are "legitimate operations" and which are not.
What I had in mind was that the following function is not
legitimate:
(defun pick-a-char (char)
(code-char (mod (+ (random char-code-limit)
(code-char char))
char-code-limit)))
In other words, manipulating characters AS CHARACTERS doesn't
extend the range beyond the domain. Playing games with char-codes
can do all sorts of weird shit, but that's not part of the semantics
of the language.
However, I didn't see
anything in the 21 Feb 89 proposal that says that CHAR-UPCASE of
a BASE-CHARACTER is necessarily a BASE-CHARACTER, for example.
That doesn't sound unreasonable, though; should it be added?
Good point. Yes, I think so.